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

为何函数未等待异步函数执行完成?TS代码问题排查

TypeScript异步请求执行顺序问题修复

问题说明

当前代码中getInfo函数调用apicall后,未等待API请求完成就输出APIres,导致结果为undefined,执行顺序不符合预期。

原代码

var APIres: any;

export class Component implements OnInit {

 async getInfo(){  
  await this.apicall();
  console.log('API response', APIres)

 }
 
 async apicall(){
   var request = new XMLHttpRequest(); 
   request.open('POST', 'URL', true);
   request.setRequestHeader('Content-Type', 'application/json');
   request.setRequestHeader('Authorization', 'Bearer ' + accessToken);
   request.onreadystatechange = async function () {
      console.log('Got Values')
      await res(JSON.parse(this.responseText));
   }
   request.send(content);
 }
}

async function res(x){console.log('out');APIres = x} //Outside of export

当前输出

API response undefined
Got Values
out

期望输出

Got Values
out
API response res

问题根源

apicall虽标记为async,但并未真正等待异步请求完成:

  • XMLHttpRequest是基于回调的异步API,onreadystatechange属于事件回调,await无法作用于该逻辑
  • apicall函数发送请求后立即返回,导致getInfo中的await直接执行后续代码

修改方案

将apicall包装为返回Promise的函数,让await能真正等待请求完成;同时移除全局变量,直接通过Promise传递结果,避免全局状态带来的问题:

修改后的代码

export class Component implements OnInit {

 async getInfo(){  
  const apiRes = await this.apicall();
  console.log('API response', apiRes)
 }
 
 apicall(): Promise<any> {
   return new Promise((resolve, reject) => {
     const request = new XMLHttpRequest(); 
     request.open('POST', 'URL', true);
     request.setRequestHeader('Content-Type', 'application/json');
     request.setRequestHeader('Authorization', 'Bearer ' + accessToken);
     
     request.onreadystatechange = async function () {
       if (this.readyState === XMLHttpRequest.DONE) {
         console.log('Got Values')
         const responseData = JSON.parse(this.responseText);
         await res(responseData);
         resolve(responseData); // 请求完成后传递结果
       }
     };

     request.onerror = function() {
       reject(new Error('Request failed')); // 处理请求错误
     };

     request.send(content);
   });
 }
}

async function res(x){console.log('out');} // 无需全局变量,移除赋值逻辑

关键修改点

  • 用Promise包裹XMLHttpRequest:让apicall返回Promise,在请求完成(readyState === 4)时调用resolve传递响应数据,请求失败时调用reject处理错误
  • 移除全局变量APIres:直接通过Promise返回结果,在getInfo中接收后使用,避免全局状态的不可预测性
  • 完善错误处理:新增onerror回调处理请求失败场景,增强代码健壮性

修改后,getInfo中的await this.apicall()会等待API请求完成并处理完res函数后,才执行后续的console.log,执行顺序完全符合预期。

内容的提问来源于stack exchange,提问作者R. Baraiya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:35:23