Sequentially process a list of asynchronous tasks using array reduce
We can use Array.reduce and Promises to sequentially process a list of async actions, such as XHR requests, ensuring they are processed in the order they are supplied.
function createSequentialProcessor(iterator) {
// return a function that accepts the items to be processed
return (items) => { // create an empty results array
const results = [] // use Array.reduce to iterate over the array
return items.reduce((promise, item, idx) => { // when the previous promise resolves...
return promise.then((result) => { // ...add the result to the results array
if (result) results.push(result) // call the iterator function with previous result
// and the next item
return iterator(result, item)
}) /// for the initial value we supply a resolved promise
}, Promise.resolve()) // finally add the last result to the results and return
.then((result) => [...results, result])
}
}
And used as
const processList = createSequentialProcessor( // create an iterator function, that does an async "request"
(previousResult, item) => { // do something with the previous result,
// possibly control the flow, throw an error etc
console.log(`Processing: ${item}`) // make request for next item, the function must return
// a promise
return fakeRequest(item)
}
)
// call the with a array of 'things'
processList(([1,2,3,4,5]))
.then((allResults) => console.log('All done', allResults))
.catch((err) => console.log('Something broke'))
See it in action: http://jsbin.com/qijaveq/edit?js,console