异步函数无法在返回数据前解析Promise数组问题排查
异步Promise处理的执行顺序问题
问题场景
编写了一个异步函数,预期解析多个Promise,将数据推入指定数组后返回该数组,但函数会在数据处理完成前就返回数组,导致返回的数组是空的或不完整。
原代码1
const responses = await Promise.all(promises) await this.resolveResponses(responses, data, ...).then( () => { return data } ) async resolveResponses(responses: Response[], data: any[],...) { responses.forEach(async (response) => { await response.json().then((responseData) => { console.log(responseData); data.push(/* 从responseData提取的内容 */) }); }); }
原代码2(单行尝试)
await Promise.all(promises) .then(promises => {promises.forEach(async promise => { const response = await promise.json() if (response.eeResponse == true) data.push(/* 从response提取的内容 */) })}).then(() => { return data })
问题原因
核心问题是**forEach不支持等待异步函数执行完成**:
forEach会遍历数组并立刻触发每个异步回调函数,但它不会收集这些异步操作返回的Promise,也不会等待所有异步任务执行完毕。- 以
resolveResponses为例,它是一个async函数,当内部的forEach遍历完成(只是触发了所有异步任务,并没有等待它们结束),函数就会直接返回一个已完成的Promise,外层的await会误以为所有处理都完成了,进而执行return data,但此时data还没被填充。 - 第二段代码的问题完全一致,
forEach内部的异步操作没被等待,后续的then就直接返回了空的data。
解决方案
把forEach替换成map,用map生成所有异步操作的Promise数组,再通过Promise.all等待所有异步任务完成:
修改后的resolveResponses函数
async resolveResponses(responses: Response[], data: any[],...) { // 用map生成每个异步操作的Promise,再用Promise.all等待全部完成 await Promise.all(responses.map(async (response) => { const responseData = await response.json(); console.log(responseData); data.push(/* 从responseData提取的内容 */); })); }
简化后的外层调用
const responses = await Promise.all(promises); await this.resolveResponses(responses, data, ...); return data;
链式调用的修正版本
await Promise.all(promises) .then(responses => Promise.all(responses.map(async (response) => { const responseData = await response.json(); if (responseData.eeResponse === true) { data.push(/* 从responseData提取的内容 */); } }))); return data;
map会将每个异步操作转换为Promise,Promise.all会等待所有这些Promise执行完成,确保所有数据都被推入data后,才会执行后续的return data。
内容的提问来源于stack exchange,提问作者andrei bulai
相关产品推荐
相关产品推荐

