Search code examples
javascriptecmascript-6async-awaites6-promiseecmascript-2017

Dynamically generate a chain of promises with async/await


Say, I need to repeat an AJAX request N times sequentially.

Normally (i. e. without async/await), I would use reduce to chain promises:

function timeout (ms = 1000) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

function request (message, ms = 1000) {
  return timeout(ms).then(() => console.log(message))
}

function makeArray (i) {
  return new Array(i).fill(null);
}

makeArray(5).reduce(
  (promise, _, i) => promise.then(() => request(i)),
  Promise.resolve()
)

How do I rewrite this code with async/await?

Instead of promise.then(() => request(i)) I want to do await request(i).

All my attempts ended up running promises in parallel. I want sequentially.


Solution

  • Remember await can only be invoked from a an async function.

    Here I've just wrapped inside a function run, it could even be an IIFE..

    In most cases when you start using async / await, you'll be calling from another async function anyway, so this little run stub wouldn't be required.

    function timeout (ms = 1000) {
      return new Promise(resolve => setTimeout(resolve, ms))
    }
    
    function request (message, ms = 1000) {
      return timeout(ms).then(() => console.log(message))
    }
    
    async function run() {
      for (let trys = 0; trys < 5; trys ++) {
        await request(trys);
      }
    }
    
    run();