JavaScript ES6 Promise Looping
In JavaScript ES6, promises offer a mechanism for asynchronous programming. However, using promises within a for loop presents a challenge, as the loop's synchronous nature can lead to unexpected behavior.
Asynchronous Promise Chaining
To ensure that each promise runs only after its predecessor has been resolved, we need to implement asynchronous promise chaining. This involves creating each promise only when the preceding one has resolved.
Promise Creation with setTimeout()
To simulate asynchronous operations, we often use setTimeout(). However, for chaining to work effectively, we need a Promise-based version of setTimeout(). Here's a function that promisifies setTimeout():
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
Solution Options
With the promisified setTimeout() in place, several options are available for asynchronous promise chaining within a for loop:
1. for Loop with Initial Promise:
This method uses a for loop that starts with an immediately resolving promise. Each iteration chains a new promise based on the result of the previous one.
for (let i = 0, p = Promise.resolve(); i < 10; i++) { p = p.then(() => delay(Math.random() * 1000) .then(() => console.log(i)); }
2. Array#reduce with Initial Promise:
This solution uses Array#reduce to iterate over a range of values and create promises based on the result of each step.
const delayAndLog = (acc, i) => acc.then(() => delay(Math.random() * 1000)) .then(() => console.log(i)); [...Array(10).keys()].reduce(delayAndLog, Promise.resolve());
3. Recursive Function with Promise Resolution:
This method involves a function that calls itself within a then callback. Each call resolves the resulting Promise when the next iteration is ready.
let i = 0; const loop = () => delay(Math.random() * 1000) .then(() => console.log(i++)) .then(loop); loop().then(() => {});
4. async/await (ES2017):
ES2017 introduced async/await, which allows for more concise asynchronous code.
async function loop() { for (let i = 0; i < 10; i++) { await delay(Math.random() * 1000); console.log(i); } } loop();
5. for await...of (ES2020):
ES2020 introduced for await...of syntax, which simplifies asynchronous iteration.
async function* loop() { for (let i of [...Array(10).keys()]) { yield await delay(Math.random() * 1000); } } for await (const i of loop()) { console.log(i); }
These solutions ensure that each promise in the loop runs only after the previous one has been resolved, as desired.
The above is the detailed content of How to Properly Handle Promise Looping in JavaScript ES6?. For more information, please follow other related articles on the PHP Chinese website!