Javascript 确保类构造函数中的异步代码在调用类方法之前完成

Javascript 确保类构造函数中的异步代码在调用类方法之前完成,javascript,asynchronous,callback,xmlhttprequest,es6-class,Javascript,Asynchronous,Callback,Xmlhttprequest,Es6 Class,我试图创建一个类,其中将文件名传递给构造函数,使用XmlHttpRequest加载文件,并将结果存储在类变量中。问题在于,request.onreadystatechange是一个异步函数,因此方法getData最终在构造函数完成之前被调用。因此,数据的结果未定义。如何确保此类的方法在运行之前等待文件加载。我对异步代码和承诺相当陌生,所以请像我5岁一样解释 如我的代码中所示,将方法包装在超时中,在某种程度上解决了这个问题,但这是一个糟糕的解决方案,request.open的同步版本由于明显的性能

我试图创建一个类,其中将文件名传递给构造函数,使用XmlHttpRequest加载文件,并将结果存储在类变量中。问题在于,
request.onreadystatechange
是一个异步函数,因此方法
getData
最终在构造函数完成之前被调用。因此,数据的结果未定义。如何确保此类的方法在运行之前等待文件加载。我对异步代码和承诺相当陌生,所以请像我5岁一样解释

如我的代码中所示,将方法包装在超时中,在某种程度上解决了这个问题,但这是一个糟糕的解决方案,
request.open的同步版本由于明显的性能问题而被贬低,因此不幸的是,这也不是一个解决方案

test.html

让test=newtestclass('test.json')
console.log(test.getData)
test.js
class测试类{
构造函数(文件名){
this.loaded_data=未定义
let request=new XMLHttpRequest()
request.overrideMimeType('application/json')
request.open('GET',filename)
request.onreadystatechange=()=>{
if(request.status='200'&&request.readyState==4){
/*在这里加载并解析JSON*/
this.loaded_data='foo'
}
}
请求发送()
}
获取getData(){
设置超时(()=>{
console.log(此.loaded_数据)
}, 500);
返回此.u数据
}
}

从设计角度来看,文件本身不是“异步的”,异步的是加载该文件。因此,类应仅表示已加载的文件:

  class File {
    constructor(content) { this.content = content; }
现在加载该文件应该是一种静态异步方法:

   static load(path) {
      return fetch(path) /*¹*/
         .then(res => res.json())
         .then(content => new File(content));
   }
 }
然后可以用作:

 (async function() {
   let file = await File.load('test.json')
   console.log(file.content);
 })()


1:XmlHttpRequest比XmlHttpRequest更易于使用,因为它返回一个承诺(因此可以很好地与
async
/
await
)配合使用),并提供一些实用程序来解析/处理响应。在这种情况下,响应被解析为JSON。

解决方案是,您也可以将
设置为this。加载的\u data
包含对数据的承诺,但这意味着使用它的所有方法都是异步的,并且承诺返回自己,这使得您的类难以使用。