欢迎光临
我的个人博客网站

JS里的异步实例化


JS里的异步构造函数

众所周知,Js的构造函数是不能加上async/await来实现异步实例化的,一般当需要一个对象的属性是异步的结果时可以这样写:

//! 一个需要指定时间后返回的异步函数 function delay(timeout) {     return new Promise((resolve) => setTimeout(() => resolve("end"), timeout)); }  class Test {     async init() {         this.end = await delay(1000);     } } (async function () {     const test = new Test(); //? 实例化     await test.init(); //? 初始化end属性     console.log(test.end); })(); 

但是当我想要在实例化时就调用该属性时就还要调用一次init(),这未免太麻烦了,所以想要在实例化时就把该属性赋值,就像这样const test = await new Test()

这时找到了这篇文章,该作者提供了这样一段代码来实现了异步构造函数:

class MyClass {   constructor(timeout) {     this.completed = false      const init = (async () => {       await delay(timeout)       this.completed = true        delete this.then       return this     })()      this.then = init.then.bind(init)   } } (async function(){     const myclass = await new MyClass(1000); })() 

在解释这段代码前就得说说PromiseLike了:一个有then方法,且该方法接收resolve,reject两个参数的对象,就像这样:

const PromiseLike = {     then(resolve) {         resolve("i am PromiseLike");     }, }; (async function () {     const something = await PromiseLike;     console.log(something); // i am PromiseLike })(); 

即使PromiseLike不是一个函数,它也会被await调用对象里的then方法并resolve出结果

现在回到刚才那段代码,注意到它最后的一段了吗

this.then = init.then.bind(init)

这句话把一个异步函数initthen给了实例,所以在调用new Myclass 后得到的实例上有着一个then方法,这个then方法又会被前面的await解析,这时实质上解析的就是init这个异步函数的then而这个then返回的是该类的实例化删除then后的this

这样await new MyClass()会等到init的异步执行完毕才会返回值,这个返回值是init的resolve。

总结一下:该方法其实仍然是同步实例化出了对象,但是await会马上异步执行实例化里then,然后返回出then里删除了then方法的this,这样就做到了一句话进行实例化并初始化异步属性。

知道了这个原理后,最初的问题就解决了:

class Test {     constructor() {         const init = (async () => {             this.end = await delay(1000);             delete this.then;             return this;         })();         this.then = init.then.bind(init);     } } (async function () {     const test = await new Test();     console.log(test.end); // end })(); 

该作者也提供了一个基类用来继承出异步构造函数,可以到原文去看看。

参考:异步构造函数 – 构造函数与Promise的结合

赞(0) 打赏
未经允许不得转载:张拓的天空 » JS里的异步实例化
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

专业的IT技术经验分享 更专业 更方便

联系我们本站主机

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏