JavaScript ES6 Promise For 循环序列化
在给定的代码中,您尝试在 for 循环中顺序执行 Promise,但遇到以下问题:循环同步执行,导致不可预测的输出。
理解问题:
Promise 封装了异步操作,但循环的同步性质会同时触发所有 Promise,而不管所需的顺序。
Promisifying setTimeout:
为了方便顺序执行,我们可以promisify setTimeout来获得一个promise,当定时器到达时就会解析过期:
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
解决方案选项:
有多种方法可以解决这个问题,利用 Promise 和异步编程技术。
1.具有初始 Promise 的 For 循环:
通过从立即解析的 Promise 开始,您可以将后续的 Promise 链接为之前的 Promise:
for (let i = 0, p = Promise.resolve(); i < 10; i++) { p = p .then(() => delay(Math.random() * 1000)) .then(() => console.log(i)); }
2.具有初始 Promise 的 Array.reduce:
使用 Array.reduce,您可以创建类似于 for 循环方法的 Promise 链:
[...Array(10)] .reduce( (p, _, i) => p.then(() => delay(Math.random() * 1000)) .then(() => console.log(i)), Promise.resolve() );
3.函数作为 Promise 解析回调:
您可以定义一个将自身传递为解析回调的函数,从而允许递归 Promise 链:
const loop = (i) => { delay(Math.random() * 1000) .then(() => console.log(i)) .then(() => { if (i < 10) loop(i + 1); }); }; loop(0);
4. async/await 语法 (ES2017):
ES2017 引入了 async/await 语法来简化异步代码处理:
const main = async () => { for (let i = 0; i < 10; i++) { await delay(Math.random() * 1000); console.log(i); } }; main();
5. for wait...of 语法 (ES2020):
ES2020 引入了一种特殊的语法来迭代异步可迭代对象:
(async () => { for await (const i of [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) { await delay(Math.random() * 1000); console.log(i); } })();
通过利用这些技术,您可以顺序执行 Promise在循环内,确保所需的操作顺序并避免不可预测的输出。
以上是如何在 JavaScript ES6 For 循环中序列化 Promise?的详细内容。更多信息请关注PHP中文网其他相关文章!