As far as I know, async/await
is just syntactic sugar over promise.then
. Consider this code snippet:
function sleep(n){
return new Promise(res => setTimeout(res, n));
}
function* range(n){
var i = 0;
while(i < n) yield i++;
}
async function doStuff(){
for(let n of range(10)){
console.log(n); // print the number
await sleep(1000); // wait for 1 second
}
}
async/await
makes the code very linear, efficient and easy to understand. One thing to keep in mind is that range
does not have to have an actual end for this to work.
The problem now is how this can be rewritten using pre-ES7 era's promise.then
. Here's a possible implementation of the same loop:
function doStuff(){
return Array.from(range(10)).reduce((acc, ele) => {
return acc
.then(() => console.log(ele))
.then(() => sleep(1000))
}, Promise.resolve());
}
Ignoring the fact that the code isn't quite elegant, the use of Array.from(range(10))
- creates an extra array that isn't needed, and
- assumes
range(10)
will end some point in the future.
Doesn't look like a good conversion.
We can also completely reinvent the wheel by using yield
as await
, but that would make the syntax non ES5-compliant. The goal here is to:
- Rewrite using ES5-compliant syntax
- Use the promise-returning
sleep
function - Dynamically chain the
sleep
promise while allowing the iterator to not have an end doStuff
can be chained:doStuff().finally(cleanUp); // clean up if something failed
(Optional) Code should not be overly complex
Any idea?