如何使用reduce()方法按顺序执行Promise? |
您所在的位置:网站首页 › 220gb是多少g › 如何使用reduce()方法按顺序执行Promise? |
看到题主专研代码的一片赤诚之心,我感动的热泪盈眶。 我这里不讲用的对与错的问题,我想题主你比谁都知道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('永远进不了的窄门'); }答案是执行到最后一个花括号,也就是第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 |