使用async reduce方法时出现result.push is not a function报错
报错原因
reduce传入的回调是async函数时,每轮回调的返回值都会被自动包装为Promise对象。第一轮迭代用初始空数组执行完push后,返回的是被包装的Promise,第二轮迭代拿到的result参数就是Promise实例,而Promise没有push方法,直接调用就会抛出类型错误。- 将初始值改为
Promise.resolve([])后问题仍存在,是因为没有在每轮迭代中先await上一轮返回的Promise,取出内部的实际数组再执行操作。 - 移除async/await后不报错但逻辑失效,是因为
axios.get()本身返回Promise,不等待请求完成就直接读取response.status,拿到的是pending状态的Promise对象,不存在status属性,状态判断逻辑完全不生效。
修复代码
串行执行版本(按数组顺序依次发起请求,和原reduce逻辑一致)
import axios from "axios"; const services = ["https://google.com", "https://facebook.com", "https://youtube.com"]; const results = await services.reduce(async (prev, service) => { // 先等待上一轮任务完成,拿到实际存储结果的数组 const resultList = await prev; // 捕获请求异常,避免单个服务请求失败中断整个流程 const response = await axios.get(service).catch(() => ({ status: 0 })); resultList.push(response.status === 200 ? `${service} is up.` : `${service} seems down.`); return resultList; }, Promise.resolve([])); console.log(results);
并行执行版本(同时发起所有请求,执行效率更高,为更常用的实现方式)
import axios from "axios"; const services = ["https://google.com", "https://facebook.com", "https://youtube.com"]; const results = await Promise.all( services.map(async (service) => { try { const response = await axios.get(service); return response.status === 200 ? `${service} is up.` : `${service} seems down.`; } catch (err) { // 网络错误、超时、非200状态码抛错的场景统一判定为服务不可用 return `${service} seems down.`; } }) ); console.log(results);
注意:直接在浏览器环境请求上述域名大概率会因为跨域策略被拦截,测试时建议在Node环境运行,或配置对应代理。
内容的提问来源于stack exchange,提问作者geminiali
相关产品推荐
相关产品推荐

