JavaScript ES6承诺循环[重复]

JavaScript ES6承诺循环[重复],第1张

JavaScript ES6承诺循环[重复]

正如您已经在问题中暗示的那样,您的代码同步创建了所有promise。相反,仅应在上一个解析时创建它们。

其次,

new Promise
需要使用调用
resolve
(或
reject
)来解决创建的每个promise。计时器到期时应执行此 *** 作。这将触发
then
您对该承诺的任何回调。为了实现链,这种
then
回调(或
await
)是必需的。

有了这些成分,有几种方法可以执行此异步链接:

  1. for
    立即解决承诺开始的循环

  2. 从此

    Array#reduce
    开始,立即解决承诺

  3. 具有将自身作为分辨率回调传递的函数

  4. 使用ECMAscript2017的

    async
    /
    await
    语法

  5. 使用建议的ECMAscript2020的

    for await...of
    语法

请在下面查看每个选项的摘要和注释。

1.与
for

可以 使用

for
循环,但是必须确保它不会
newPromise
同步执行。相反,您可以创建一个初始的立即解决的Promise,然后在先前的Promise解析时链接新的Promise:

for (let i = 0, p = Promise.resolve(); i < 10; i++) {    p = p.then(_ => new Promise(resolve =>        setTimeout(function () { console.log(i); resolve();        }, Math.random() * 1000)    ));}
2.用
reduce

这只是先前策略的一种更实用的方法。您创建一个长度与要执行的链相同的数组,并以立即解决的承诺开始:

[...Array(10)].reduce( (p, _, i) =>    p.then(_ => new Promise(resolve =>        setTimeout(function () { console.log(i); resolve();        }, Math.random() * 1000)    )), Promise.resolve() );

当您实际上有 一个包含要在诺言中使用的数据的数组时,这可能会更有用。

3.具有将自身传递为分辨率回调的功能在这里,我们创建一个函数并立即调用它。它同步创建第一个承诺。解析后,将再次调用该函数:
(function loop(i) {    if (i < 10) new Promise((resolve, reject) => {        setTimeout( () => { console.log(i); resolve();        }, Math.random() * 1000);    }).then(loop.bind(null, i+1));})(0);

这将创建一个名为的函数

loop
,在代码的最后,您可以看到它立即被参数0 调用。这是计数器,还有 i
参数。如果该计数器仍低于10,该函数将创建一个新的Promise,否则链接将停止。的调用
resolve()
将触发
then
回调,该回调将再次调用该函数。
loop.bind(null, i+1)
只是一种不同的表达方式
_ =>loop(i+1)

4.使用
async
/
await

现代JS引擎支持以下语法:

(async function loop() {    for (let i = 0; i < 10; i++) {        await new Promise(resolve => setTimeout(resolve, Math.random() * 1000));        console.log(i);    }})();

看起来 好像是

new Promise()
调用是同步执行的,这看起来可能很奇怪,但实际上,该
async
函数在执行first时返回
await
。每次等待的promise解析后,该函数的运行上下文都将还原,并在之后执行
await
,直到遇到下一个,然后继续进行直到循环结束。

由于根据超时返回承诺是很平常的事情,因此您可以创建一个单独的函数来生成此类承诺。在这种情况下,这称为“ 函数”

setTimeout
。它可以提高代码的可读性:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));(async function loop() {    for (let i = 0; i < 10; i++) {        await delay(Math.random() * 1000);        console.log(i);    }})();
5.用
for await...of

甚至在最近,该

for await...of
语法也被一些Javascript引擎使用。尽管在这种情况下它并没有真正减少代码,但是它允许将随机间隔链的定义与它的实际迭代隔离开:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));async function * randomDelays(count ,max) {    for (let i = 0; i < count; i++) yield delay(Math.random() * max).then(() => i);}(async function loop() {    for await (let i of randomDelays(10, 1000)) console.log(i);})();


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5021937.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-15
下一篇 2022-11-15

发表评论

登录后才能评论

评论列表(0条)

保存