为什么在reduce中使用async函数仅返回最后一个元素的处理结果
问题原因
- 第一个错误是数组定义语法错误:你写的
[("apple", "banana", "orange")]中,小括号内部的逗号属于逗号运算符,会依次执行每个表达式并返回最后一个的结果,所以这行代码实际生成的数组只有"orange"一个元素,自然只能得到最后一个元素的处理结果。 - 第二个错误是
reduce搭配异步函数的逻辑错误:异步函数的返回值始终是Promise对象,你第一轮迭代返回的是封装了结果对象的Promise,第二轮拿到的累加参数o实际是这个Promise实例,不是你想要的普通对象,直接展开...o肯定得不到预期结果。
修复方案
首先修正数组定义,其次在每次迭代时先await上一轮返回的累加Promise,拿到真实的累加对象后再操作,正确代码如下:
(async () => console.log( await ["apple", "banana", "orange"].reduce(async (prevPromise, fruit) => { // 先等待上一轮的异步累加结果 const o = await prevPromise; const random_number = await new Promise((resolve) => setTimeout(() => resolve(Math.random()), 200)); return { ...o, [fruit]: random_number }; }, Promise.resolve({})) // 初始值也用Promise包裹,保证第一次迭代的await逻辑一致 ))();
如果你不需要按顺序执行异步操作,用Promise.all处理性能会更高,总耗时仅需200ms左右,不需要串行等待三次计时器:
(async () => { const fruits = ["apple", "banana", "orange"]; const pairs = await Promise.all( fruits.map(async fruit => { const random_number = await new Promise(resolve => setTimeout(() => resolve(Math.random()), 200)); return [fruit, random_number]; }) ); console.log(Object.fromEntries(pairs)); })();
内容的提问来源于stack exchange,提问作者Slinidy
相关产品推荐
相关产品推荐

