I am using a generator function to emulate an iterable task queue:
function* taskQueue() {
for(let i=0; i<10; i++) {
yield new Promise((resolve) => {
setTimeout(() => resolve(i), (11 - i)*1000)
})
}
}
The timeouts should cause the promises to resolve in reverse order (assuming all started at the same time), with the longest completing in 11 seconds.
Iterating over the promises, and using Promise.then(), the code takes the length of the longest timeout (11 seconds) to complete:
function then() {
let q = taskQueue();
for(i of q) {
i.then(console.log)
}
}
However, if I await the promises instead then they resolve in order and it takes linear time (66 seconds) to complete:
async function awaiting() {
let q = taskQueue();
for(i of q) {
let n = await i;
console.log(n);
}
}
It appears that this is because the next promise is not being yielded by taskQueue before the previous one resolves, since if I push them onto an array and then await, the code executes in 11 seconds:
async function awaiting2() {
let q = taskQueue();
let tasks = [];
for(i of q) {
tasks.push(i);
}
for(i of tasks) {
let n = await i;
console.log(n);
}
}
So why is it that the promises are resolved concurrently in the case of then(), but not in the case of awaiting()?