Reputation:
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?
Upvotes: 0
Views: 191
Reputation: 116200
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.
Upvotes: 2