TypeScript:异步API调用完成前函数返回问题及可行方案
解决异步函数提前返回导致数据错误的问题
我一眼就看出你碰到了JavaScript异步编程里的典型坑——createFileReqInfo里的API调用还没拿到结果,函数就先返回了,所以你push到fileReqInfo里的根本不是正确的返回值,大概率是个未完成的Promise或者undefined。
问题根源
JavaScript的异步操作不会阻塞代码执行,你的循环会一口气跑完所有迭代,每一次调用createFileReqInfo后,不等它内部的API请求返回,就直接把它的返回值(可能是Promise)push进数组了,自然拿不到正确的结果。
解决方案
我们可以用async/await或者Promise.all来解决这个时序问题,具体分两种场景:
场景1:需要串行执行异步操作(一个请求完成再发下一个)
把整个收集逻辑放到一个async函数里,用await等待每个createFileReqInfo完成:
async collectSelectedRowInfo() { const fileReqInfo = []; // 遍历选中的行 for (const row of this.selectedItems()) { // 等待异步操作完成,拿到正确的info const info = await this.createFileReqInfo(row.Number(), FileRequestType.AssociatedDoc); fileReqInfo.push(info); } // 这里的fileReqInfo就是完整的正确数据,可以传给后续处理逻辑 return fileReqInfo; } // 调用这个函数时,也要用await或者.then处理结果 collectSelectedRowInfo().then(processedData => { // 你的后续处理代码 }).catch(error => { // 处理可能的错误 });
场景2:允许并行执行异步操作(速度更快,适合无依赖的请求)
如果各个行的API请求之间没有依赖关系,推荐用Promise.all同时发起所有请求,效率更高:
// 先把所有异步请求转换成Promise数组 const requestPromises = this.selectedItems().map(row => { return this.createFileReqInfo(row.Number(), FileRequestType.AssociatedDoc); }); // 等待所有Promise都完成 Promise.all(requestPromises).then(fileReqInfo => { // fileReqInfo是按顺序排列的所有正确结果 // 后续处理逻辑 }).catch(error => { // 只要有一个请求失败,就会进入这里 });
关键前提:createFileReqInfo必须返回Promise
上面的方案能生效的前提是,你的createFileReqInfo函数要返回一个Promise,这样await和Promise.all才能正确等待异步操作完成。如果原来的函数没做这件事,需要改造它:
// 用async/await改造createFileReqInfo async createFileReqInfo(number, requestType) { // 假设你用fetch发起API请求 const response = await fetch(`/your-api-endpoint?number=${number}&type=${requestType}`); const apiData = await response.json(); // 处理API返回的数据,生成需要的info对象 const info = { // 根据apiData构造你的info结构 number: number, type: requestType, data: apiData }; return info; }
这样改造后,createFileReqInfo就会返回一个Promise,等待内部的API请求完成后才会resolve出正确的info。
内容的提问来源于stack exchange,提问作者EdR
相关产品推荐
相关产品推荐

