How to execute promises sequentially, passing the parameters from an array?

You can make the repeated application of .then into a fold pretty neatly if you’re okay with creating as many promises as array elements as is the case in the question:

myArray.reduce(
  (p, x) =>
    p.then(() => myPromise(x)),
  Promise.resolve()
)

but given support, an async function is a better choice. It’s nicely readable and has O(1) instead of O(n) memory overhead.

const forEachSeries = async (iterable, action) => {
  for (const x of iterable) {
    await action(x)
  }
}

forEachSeries(myArray, myPromise)

If you want to collect the return values as an array, that’s:

const mapSeries = async (iterable, fn) => {
  const results = []

  for (const x of iterable) {
    results.push(await fn(x))
  }

  return results
}

or, without async function support,

const mapSeries = (iterable, fn) => {
  const iterator = iterable[Symbol.iterator]()
  const results = []
  const go = () => {
    const {value, done} = iterator.next()

    if (done) {
      return results
    }

    return fn(value).then(mapped => {
      results.push(mapped)
      return go()
    })
  }

  return Promise.resolve().then(go)
}

Runnable snippet:

const myArray = [1, 2, 3, 4, 5, 6]

const sleep = ms =>
  new Promise(res => {
    setTimeout(res, ms)
  })

const myPromise = num =>
  sleep(500).then(() => {
    console.log('done: ' + num)
  })

const forEachSeries = async (iterable, action) => {
  for (const x of iterable) {
    await action(x)
  }
}

forEachSeries(myArray, myPromise)
  .then(() => {
    console.log('all done!')
  })

Don't create an array of promises. Create an array of functions returning a promise.

const f = x => new Promise(resolve => setTimeout(() => resolve(console.log(x)), 2000))

(async () => {
    for (let job of [1, 2, 3, 4, 5, 6].map(x => () => f(x)))
        await job()
})()

Promises start running immediately after creation. Therefore, sequential execution is ensured by constructing the next promise only after finishing the current one.

Tags:

Javascript