Node.js Typescript异步函数返回更新前数据问题排查
问题诱因
- 核心原因是
Array.prototype.forEach方法本身不支持异步等待逻辑:你传入的异步回调会返回Promise实例,但forEach不会收集这些Promise,也不会等待任意一个回调执行完成,遍历操作会同步执行结束。 - 你代码中的
await lists.forEach(...)实际等待的是forEach的返回值(固定为undefined),相当于没有等待任何异步操作完成,函数会直接返回初始状态的result对象,后续异步回调中对result的修改发生在函数返回之后,所以你拿到的永远是更新前的状态。
解决方案
你可以根据业务需要选择串行或并行的执行方案:
方案1:串行执行(按顺序处理每个元素,适用于接口有调用频率限制的场景)
将forEach替换为支持异步等待的for...of循环:
async migrateCustomerImageUseCase(request: ListCustomerForMigration, response: Response): Promise<any>{ const result = {} as any const lists = request as any for (const element of lists) { const msisdn = element[0] as string const isCustomerExist = await this.ekycHandler.isCustomerExist(msisdn) if(isCustomerExist){ result[msisdn] = "customer exist" as string this.logger.info(`${msisdn} = ${result[msisdn]}`); } else { result[msisdn] = "customer not exist" as string this.logger.info(`${msisdn} = ${result[msisdn]}`); } } return result }
方案2:并行执行(所有异步请求同时发起,性能更高,适用于无调用限制的场景)
用Array.prototype.map将所有异步操作转为Promise数组,再用Promise.all等待全部执行完成:
async migrateCustomerImageUseCase(request: ListCustomerForMigration, response: Response): Promise<any>{ const result = {} as any const lists = request as any await Promise.all(lists.map(async (element: any[]) => { const msisdn = element[0] as string const isCustomerExist = await this.ekycHandler.isCustomerExist(msisdn) if(isCustomerExist){ result[msisdn] = "customer exist" as string this.logger.info(`${msisdn} = ${result[msisdn]}`); } else { result[msisdn] = "customer not exist" as string this.logger.info(`${msisdn} = ${result[msisdn]}`); } })) return result }
内容的提问来源于stack exchange,提问作者mhaniffatur
相关产品推荐
相关产品推荐

