Reputation: 1987
Trying to loop through a for
loop and do something but await every iteration of that for loop to complete, the for loop wont know how many items it has in the real application.
test
async function getList(){
return new Promise( (resolve, reject) => {
let out = [];
for (let n=0; n <= 4; n++){
// new Promise( (resolve, reject) => {});
let time = (n+1) * 250;
new Promise(resolve => setTimeout(()=>{
log(n);
out.push(n);
resolve();
}, time));
}
// How do I get this resolve to run only once all the for looped promises are complete?
resolve(out);
});
}
function test(){
let numbers = false;
log("start");
log(numbers); // logs false (correct);
getList().then((v)=>{
log("v = " + v); // this should be an array of ints 0 to 4
log("completed");
})
}
console.clear();
test();
output:
I need 0 to 4 to block the process and then log complete.
Upvotes: 0
Views: 287
Reputation: 82096
In the first example, you don't need to mark getList
as async
(you don't use await
at the top-level). The crux of the problem is that setTimeout
is a non-blocking operation therefore your Promise is resolving before the array has a chance to populate.
In the second example, you are using await
but on a non-awaitable item (numbers
is just an array), therefore the same issue as above applies (the Promise will resolve before the array has populated).
If in your "real world" application you have an example of where you need to wait for a fixed period, and this needs to happen in sequential order, then you could create an awaitable setTimeout
e.g.
const sleep = timeout => new Promise(resolve => setTimeout(resolve, timeout));
async function getList() {
const numbers = [1,2,3,4,5,6,7,8,9,10];
const out = [];
for (const n in numbers) {
await sleep(50);
out.push(n);
}
return out;
}
Upvotes: 1