Darcey
Darcey

Reputation: 1987

nodejs async for await issue

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

Answers (1)

James
James

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

Related Questions