Passing Parameters Sequentially through Promises with Array Iteration
Consider the following task:
var myArray = [1, 2, 3, 4, 5, 6]</p> <p>function myPromise(num){<br> return new Promise(res => {</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">window.setTimeout(()=>{ res( console.log("done: " + num) ) },2000)
})
}
myPromise(myArray[0])
.then(x => myPromise(myArray[1]))
.then(x => myPromise(myArray[2]))
.then(x => myPromise(myArray[3]))
.then(x => myPromise(myArray[4]))
.then(x => myPromise(myArray[5]))
Code like the above will execute promises sequentially. However, if the array is dynamically populated, executing myPromise() for each member becomes challenging.
Pauseable Iteration with Promises
To create a "pauseable loop" that executes myPromise() sequentially, waiting for resolution before continuing:
Fold Method
myArray.reduce( (p, x) => p.then(() => myPromise(x)), Promise.resolve() )
This method creates as many promises as array elements, but it's a neat solution if this is acceptable.
Async Function Method
const forEachSeries = async (iterable, action) => { for (const x of iterable) { await action(x) } } forEachSeries(myArray, myPromise)
Async functions offer a more readable and memory-efficient solution.
Collecting Return Values
If you want to collect return values as an array:
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) }
Usage Example
A runnable snippet using the forEachSeries method:
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!') })
The above is the detailed content of How to Sequentially Pass Parameters through Promises with Array Iteration?. For more information, please follow other related articles on the PHP Chinese website!