Using “await” inside non-async function

后端 未结 3 1679
梦如初夏
梦如初夏 2020-12-23 16:19

I have an async function that runs by a setInterval somewhere in my code. This function updates some cache in regular intervals.

I also have a different, synchronous

3条回答
  •  囚心锁ツ
    2020-12-23 16:54

    Now, this can be easily circumvented by extracting the logic inside updateCacheForKey into a new synchronous function, and calling this new function from both existing functions.

    T.J. Crowder explains the semantics of async functions in JavaScript perfectly. But in my opinion the paragraph above deserves more discussion. Depending on what updateCacheForKey does, it may not be possible to extract its logic into a synchronous function because, in JavaScript, some things can only be done asynchronously. For example there is no way to perform a network request and wait for its response synchronously. If updateCacheForKey relies on a server response, it can't be turned into a synchronous function.

    It was true even before the advent of asynchronous functions and promises: XMLHttpRequest, for instance, gets a callback and calls it when the response is ready. There's no way of obtaining a response synchronously. Promises are just an abstraction layer on callbacks and asynchronous functions are just an abstraction layer on promises.

    Now this could have been done differently. And it is in some environments:

    • In PHP, pretty much everything is synchronous. You send a request with curl and your script blocks until it gets a response.
    • Node.js has synchronous versions of its file system calls (readFileSync, writeFileSync etc.) which block until the operation completes.
    • Even plain old browser JavaScript has alert and friends (confirm, prompt) which block until the user dismisses the modal dialog.

    This demonstrates that the designers of the JavaScript language could have opted for synchronous versions of XMLHttpRequest, fetch etc. Why didn't they?

    [W]hy absolutely prevent this use case in the first place?

    This is a design decision.

    alert, for instance, prevents the user from interacting with the rest of the page because JavaScript is single threaded and the one and only thread of execution is blocked until the alert call completes. Therefore there's no way to execute event handlers, which means no way to become interactive. If there was a syncFetch function, it would block the user from doing anything until the network request completes, which can potentially take minutes, even hours or days.

    This is clearly against the nature of the interactive environment we call the "web". alert was a mistake in retrospect and it should not be used except under very few circumstances.

    The only alternative would be to allow multithreading in JavaScript which is notoriously difficult to write correct programs with. Are you having trouble wrapping your head around asynchronous functions? Try semaphores!

提交回复
热议问题