如何解决类async异步方法初始化成员时构造函数调用时序异常问题
问题根因
- JavaScript的类构造函数不支持异步等待,你直接调用
AsyncMethodInsideClass时,它会立即返回一个pending状态的Promise,不会阻塞后续代码执行,所以processNewObject运行时异步逻辑还没走完,this.newObject自然是undefined。 - 注意不要尝试给构造函数加
async修饰符,JavaScript语法不支持异步构造函数,运行会直接报错。
可落地的解决方案
以下是3种常用的可行方案,推荐优先用第一种:
方案1:静态工厂方法(最稳妥)
通过静态异步方法完成初始化后再返回实例,从根源上避免返回半初始化的实例,代码示例:
class YourClass { // 构造函数仅做同步初始化逻辑 constructor() {} async asyncMethodInsideClass() { // 原有异步逻辑修正了变量名、语法错误 const request1 = await fetch(/* 你的请求参数 */); const request2 = await request1.json(); for(const object of request2.objects){ if(object.name === "Founded") { this.newObject = object } } } // 静态异步工厂方法 static async create() { const instance = new YourClass(); // 等待异步初始化完全结束 await instance.asyncMethodInsideClass(); // 此时newObject已经赋值完成,再执行处理逻辑 processNewObject(instance.newObject); return instance; } } // 调用方式 const yourInstance = await YourClass.create();
方案2:构造函数内挂载初始化Promise
如果你不想修改实例创建的调用方式,可以把异步初始化的Promise挂载到实例上,后续逻辑放到then回调中执行:
class YourClass { constructor() { // 把初始化Promise挂到实例上,外部也可以用来等待初始化完成 this.initPromise = this.asyncMethodInsideClass().then(() => { processNewObject(this.newObject); }); } async asyncMethodInsideClass() { // 同方案1的异步逻辑 const request1 = await fetch(/* 你的请求参数 */); const request2 = await request1.json(); for(const object of request2.objects){ if(object.name === "Founded") { this.newObject = object } } } } // 外部如果需要等待初始化完成再操作实例,调用方式如下: const yourInstance = new YourClass(); await yourInstance.initPromise; // 这里可以保证newObject已经赋值完成
方案3:调整processNewObject的触发时机
如果processNewObject不需要给实例创建者返回值,直接把它的调用放到异步方法的末尾即可,改动最小:
class YourClass { constructor() { this.asyncMethodInsideClass(); } async asyncMethodInsideClass() { const request1 = await fetch(/* 你的请求参数 */); const request2 = await request1.json(); for(const object of request2.objects){ if(object.name === "Founded") { this.newObject = object } } // 异步逻辑走完,newObject赋值完成后再调用处理方法 processNewObject(this.newObject); } }
内容的提问来源于stack exchange,提问作者Icaro Amorim
相关产品推荐
相关产品推荐

