How to write an Asynchronous Loop using Promises?

Viewed 71

How do I write a synchronous loop using Promises? Neither of the functions below wait for the previous loop to finish before starting...

(async ()=> {
    let arr = [3,1,2,1,2];

    const waitFor = ms => new Promise(r => setTimeout(r, ms));

    // Using Promise.all
    const firstFn = async () => { // doens't work
        return Promise.all(arr.map(async (sec) => {
            await waitFor(sec*1000);
            console.log(`waited for ${sec} seconds`);
        }));
    }
    await firstFn();

    // Using new Promise
    const secondFn = async () => {
        arr.map(sec => {
            new Promise(async (res, rej) => {
                await waitFor(sec*1000);
                console.log(`waited for ${sec} seconds`);
                res();
            });
        });
    }
    await Promise.all(secondFn());

})();
3 Answers

map process the promises in a parallel execution. If you want in sequence use for... of , or the simple form of the for. Example:

async function something () {
  const arr = [3,1,2,1,2];
  for (let x = 0; x < arr.length; x++) {
    const sec = arr[x];
    await waitFor(sec*1000);
    console.log(`waited for ${sec} seconds`);
  }
}

Here's an example of an asynchronous function that takes a list of asynchronous functions and executes them sequentially. Waiting for one to finish before moving to the other.

const wait =
  ms =>
    new Promise
      ( resolve =>
          setTimeout
            ( () => (console.log(`wait ${ms}`), resolve())
            , ms
            )
      );

const async_chain =
  async ([fn, ...fns]) =>
    typeof fn === 'function'
      ? (await fn(), await async_chain(fns))
      : undefined;

(async function main() {

  await async_chain
    ( [ async () => wait(1000)
      , async () => wait(2000)
      , async () => wait(3000)
      ]
    )

})();

Related