0

While reading up on some async/await examples with the new javascript syntax, I found this code example:

const axios = require('axios'); // promised based requests - like fetch()

function getCoffee() {
  return new Promise(resolve => {
    setTimeout(() => resolve('☕'), 2000); // it takes 2 seconds to make coffee
  });
}

async function go() {
  try {
    // but first, coffee
    const coffee = await getCoffee();
    console.log(coffee); // ☕
    // then we grab some data over an Ajax request
    const wes = await axios('https://api.github.com/users/wesbos');
    console.log(wes.data); // mediocre code
    // many requests should be concurrent - don't slow things down!
    // fire off three requests and save their promises
    const wordPromise = axios('http://www.setgetgo.com/randomword/get.php');
    const userPromise = axios('https://randomuser.me/api/');
    const namePromise = axios('https://uinames.com/api/');
    // await all three promises to come back and destructure the result into their own variables
    const [word, user, name] = await Promise.all([wordPromise, userPromise, namePromise]);
    console.log(word.data, user.data, name.data); // cool, {...}, {....}
  } catch (e) {
    console.error(e); // 
  }
}

go();

One thing that is not clear (in the linked example the whole script waits for the the coffee function to return), it appears to be that async/await is a blocking action? If this is the case does this not mean it is a bad idea for a node web application?

I have just been thrown into a project using AWS DynomoDB whose abstraction class for all actions is behind async/await... if this is blocking, this will surely destroy performance?

Pierre C.
  • 1,591
  • 2
  • 16
  • 29
  • 4
    The word `async` tells you it's *asynchronous*. It's just a language-construct to help the developer use synchronous coding technique in order to implement asynchronous pattern without promises / callbacks. So, your question actually makes no sense. – Mjh Oct 05 '17 at 15:45
  • 2
    No, `await` doesn't block. It's just syntactic sugar for a callback. – Barmar Oct 05 '17 at 15:45
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) (see accepted answer, heading **ES2017+: Promises with async/await**) – Igor Oct 05 '17 at 15:45
  • Where did you get the idea that `async`/`await` was blocking? – Sebastian Simon Oct 05 '17 at 15:45
  • Your question is based on a false understanding. `await` doesn't block the whole system. Think of it instead as pausing that specific code from continuing, but allowing the calling code to go do something else while this code waits. Nothing is blocked, and ultimately this is the exact same behavior as using a callback. It just simplifies the syntax of invoking that callback. – David Oct 05 '17 at 15:46
  • 2
    Read the description of `await` at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await. In particular, note that it says **It can only be used inside an async function.** – Barmar Oct 05 '17 at 15:47
  • In other languages there is similar syntax, eg sleep in php. Await leads one to think that possibly the script would await for an action to complete before continuing. –  Oct 05 '17 at 15:47
  • Yup, makes sense now peeps thanks for the answers and clarification. –  Oct 05 '17 at 15:48
  • 2
    @John: sleep in PHP is *not* the same thing. That *does* block the entire thread. Admittedly when I first saw async/await (in C#) it didn't quite sink in either right away. The word "await" implies to me, well, waiting. But the key here is that it's only *that function* that's waiting. What *called* that function is not waiting. – David Oct 05 '17 at 15:48
  • yup.. better safe than sorry.. and most sure fire way to get an answer to a Q like this is to ask the community. Thanks again. –  Oct 05 '17 at 15:49

1 Answers1

2

await does block! ..

await indeed makes your code wait. There is no magic that will let the code that comes after the await run while you're still waiting. In the example, those ajax requests are not going to be fired until the coffee is done.

..but it can wait for multiple asynchronous jobs..

However, you can await multiple asynchronous processes. The example that you post at some point fires three simultaneous Ajax requests and waits for those only after they have all been fired. Those requests will be executed in parallel.

..you only have to wait when you need answers

The point is that you start something asynchronously, which will eventually end (promise!). You can call await when (and preferably only when) you really need to wait on the result of that call. So if you call every async method using await, then the effect is gone, but if you call them, store the promise in a variable, and then await them at the end, then you're running your long actions in parallel. The example shows the "bad" use (getting coffee and not getting to work until it's done), and then the good use (doing three requests at the same time).

You could 'optimize' the example by only awaiting the coffee and the first request at the end, just like it waits for the other requests, so it does 5 things in parallel instead of 3. This only works when you don't need the result of the first async function in the next.

.. and await blocks only you, not your caller

I said before that calling await right away for a single synchronous function is bad. This is not always the case, because you can only use await in a function that is asynchronous itself, so the caller of your function isn't blocked (unless it also calls await).

So for example you could make a simple function for fetching some data, that wraps a more complicated Ajax call using await AjaxShizzleGoesHere(). Even though your function just calls one other thing and awaits it, it is still possible to run it in parallel. Your function has to wait for the Ajax call to return (so it uses await, and is blocked), but the caller of your function doesn't have to await the result right away, and it can start other asynchronous functions first.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210