You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript使用reduce处理混合同步异步函数数组报错如何解决

问题原因

  • 所有被async修饰的函数,返回值永远是Promise实例,和你return的内容无关。你在reduce中传入的回调是async函数,所以每一轮迭代返回的累加器本质都是Promise,而非处理后的person对象。
  • 你只对当前执行的fn做了await,没有对前一轮返回的累加器做await,所以第二轮执行同步方法formatAge时,传入的参数是Promise实例,自然读取不到name、age等属性,触发报错。
  • 移除同步方法后所有迭代都是异步逻辑,内部自动处理了Promise解析,所以不会报错。

解决方案

只要在每轮迭代执行处理函数前,先await上一轮的累加器即可。await对同步值没有副作用,也能正常解析Promise实例,完美兼容同步、异步函数混合的场景。
修正后的完整代码如下:

const formatName = (person) => {
    person.name = person.name.toUpperCase();
    return person;
}

const formatAge = (person) => {
    person.age += 10;
    return person;
}

// Async function  
const formatLocation = async (person) => {
    await new Promise(resolve => setTimeout(resolve, 1000));
    person.location = `${person.location.toLocaleLowerCase()}`
    return person;
}

const initialPerson = {
    name: "john",
    age: 35,
    location: 'USA'
}

const formattedStagesWithAsync = [
    formatLocation, // asynchronous
    formatAge, // synchronous
    formatName //synchronous
];

const process = async () => {
    const formattedPerson = await formattedStagesWithAsync.reduce(async (prevResultPromise, fn) => {
        // 先解析上一轮的结果,兼容同步、异步返回值
        const prevResult = await prevResultPromise;
        const results = await fn(prevResult);
        return results;
      }, initialPerson);

    console.log(`Formatted person - ${JSON.stringify(formattedPerson, null, 2)}`);
}   

process();

运行后输出结果为:

Formatted person - {
  "name": "JOHN",
  "age": 45,
  "location": "usa"
}

内容的提问来源于stack exchange,提问作者John Grayson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:36:02