I'd like to learn if there is a right answer of where to wait for async operations. If this is a topic with depth I'm also happy to receive articles or programming-terms to read up on.
Let's say we have a slow async operation, perhaps reading a large file:
const resolver = (x) => {
return new Promise(resolve => {
setTimeout(() => {resolve(x)}, 500)
})
}
I can see two ways to use resolver
:
const one = async () => {
const result = await resolver('foo')
console.log(result)
}
const two = async () => {
const result = resolver('foo')
console.log(await result)
}
(Note the differently placed await
keyword)
In one
we immediately wait, and this is the pattern I've been exposed to. I think it's the normal and expected pattern?
But should that line really wait for the result? It doesn't really need it resolved, right? result
is only really consumed on the next line.. so why not wait there, as two
illustrates?
There's obviously no gain in clarity for this trivial example, but in a larger function with multiple awaits and multiple consumers of the asynchronous result, I can maybe see it will be clearer to have the await
colocated where it is actually required, rather than an upfront wait just because later code needs it.
Any right answers? Or thoughts? And if this is all a giant waste of worry then I'm happy to learn of that too :)
You're absolutely right. In larger pieces of code, where you put await matters.
The following is an example of how the two styles lead to completely different interpretations:
// Example 1 - serial async operations
async function () {
var a = await foo();
var b = await bar();
console.log(a+b);
}
Assuming that foo
and bar
each takes one second to return results, the above code will take roughly two seconds to execute.
// Example 2 - parallel async operations
async function () {
var a = foo();
var b = bar();
var aa = await a;
var bb = await b;
console.log(aa+bb);
}
Making the same assumptions as the first example, the above code would take roughly one second to execute because bar
will be executed in parallel without waiting for foo
to complete.