如何使用reduce()方法按顺序执行Promise?

您所在的位置:网站首页 220gb是多少g 如何使用reduce()方法按顺序执行Promise?

如何使用reduce()方法按顺序执行Promise?

#如何使用reduce()方法按顺序执行Promise?| 来源: 网络整理| 查看: 265

看到题主专研代码的一片赤诚之心,我感动的热泪盈眶。

我这里不讲用的对与错的问题,我想题主你比谁都知道Array.reduce、Await和Promise怎么用。我只解释一下为什么会这样。

原理两个reduce作为同步循环函数不管里面的异步callback是否执行完毕,都会拿着上一个函数return的返回值(有可能是Promise实例)作为acc去塞到下一次的callback函数里await之后的函数需要执行的resolved(reject或者resolve)状态才会去走下一行的代码,如果是等待中的状态,会一直等下去,就像等待戈多~(跑偏ing)原理一

reduce作为同步循环函数不管里面的异步callback是否执行完毕,都会拿着上一个函数return的返回值(有可能是Promise实例)作为acc去塞到下一次的callback函数里

const neverResolve = ()=>{ return new Promise(()=>{ }) } const arr = [1,2,3,4] const result = arr.reduce(async (acc, curr, index)=>{ console.log(acc, 'acc', Date.now()); await neverResolve(); }, 'foo') console.log(result);

红框内的时间一模一样,reduce不管你里面是什么,直接挨个执行。

但问题来了,第一个acc给了‘foo’, 下一个callback的acc给什么呢?看绿框是Promise实例。

众所周知,async返回的是Promise,那就给Promise吧,具体这个异步对象返回什么,reduce才不管呢,给就完事了。

原理二

await之后的函数需要执行的resolved状态才会去走下一行的代码,如果是等待中的状态,会一直等下去。

问题 如果await后的函数一直到不了resolved呢?

一直等下去

const neverResolve = ()=>{ return new Promise(()=>{ }) } const fetchData = async ()=>{ await neverResolve(); console.log('永远进不了的窄门'); }问题 什么时候async函数真正的执行完?

答案是执行到最后一个花括号,也就是第14行

问题二 如果async函数里没有return呢?

当执行到花括号时,async函数还是没有return任何返回值。那就返回Promise包着的undefined,也是resolved状态的。

回到题目

我将题主的代码加了几个log,可以更清晰的说明问题。

const list = [1, 2, 3] const square = (num)=>{ return new Promise((resolve)=>{ setTimeout(() => { resolve(num * num) }, 1000); }) } const output = (arr)=>{ return arr.reduce(async (acc, curr, index)=>{ console.log('before await acc', acc, curr , Date.now()); await acc; console.log('before await square', acc, curr , Date.now()); const result = await square(curr) console.log('after await square', acc, curr , Date.now()); console.log(result); }, 'foo') } const result = output(list) console.log('outputResult', result);

问:为什么'before await acc'在同一时间?

答案:reduce同步代码执行根本不管callback同步异步,直接扔了Promise过去,这也是outputResult直接输出的原因。至于outputResult为什么输出了Promise这是另一个问题了

问: before await square foo 1 1646278451464 为什么也在同一时间?

答案: 因为第一个acc为foo字符串,根本不用等,直接就过了。但由于是在微任务中(在await下一行),所以在同步代码循环之后输出

问:after await square foo 1 1646278452465 为什么在一秒之后输出

答案:因为Promise执行了一秒,这个很浅显了。

问: before await square Promise {: undefined} 2 1646278452465 为什么和第一次callback返回数据时的时间一样?

答案:2一直在等待1的acc返回,这是一秒后1的acc返回了后,2的await acc继续走的结果。几个callback的执行是同步的。1的callback已经讲完了,2、3其实也执行了,但由于await在等着acc到resolved状态。所以在1在等foo,2在等1的acc,3在等2的acc。这也是每隔一秒输出一次的原因。

问:为什么去掉await acc后直接1秒后全部输出了呢?

reduce直接顺序执行所有的callback,一秒后各自都resolved了。所以一起输出,callback的执行顺序就是reduce的1、2、3顺序。

帮到你,麻烦点赞 。

有错误,欢迎指正 。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3