31

正如问题所述。我是否可以这样做:

class MyClass {
    async constructor(){
        return new Promise()
    }
}
4

4 回答 4

59

为了扩展帕特里克·罗伯茨所说的,你不能做你所要求的,但你可以做这样的事情:

class MyClass {
  constructor() {
     //static initialization
  }

  async initialize() {
     await WhatEverYouWant();
  }

  static async create() {
     const o = new MyClass();
     await o.initialize();
     return o;
  }
}

然后在您的代码中创建您的对象,如下所示:

const obj = await MyClass.create();
于 2017-11-29T18:00:29.210 回答
15

在不试图预测未来决定的情况下,让我们专注于实用性和已知的事情。

ES7,就像之前的 ES6 一样,它会尝试成为一种向后兼容的语言扩展。考虑到这一点,向后兼容的构造函数本质上是一个常规函数(具有一些运行时限制),旨在使用new关键字调用。发生这种情况时,函数的返回值会得到特殊处理,具体来说,非对象返回值将被忽略并返回新分配的对象,而对象返回值按原样返回(并且新分配的对象被丢弃)。这样,您的代码将导致返回一个承诺,并且不会发生“对象构造”。我看不出这样做的实用性,我想如果有人花时间找到如何处理此类代码,它将被拒绝。

于 2016-04-01T18:32:12.490 回答
15

简而言之:

  1. 构造函数是一个需要提供具体对象的函数。
  2. 异步返回一个承诺;与具体性完全相反。
  3. async constructor在概念上是矛盾的。
于 2016-04-08T04:57:40.977 回答
7

你可以从返回值中得到一个承诺,然后等待:

class User {
  constructor() {
    this.promise = this._init()
  }
  
  async _init() {
    const response = await fetch('https://jsonplaceholder.typicode.com/users')
    const users = await response.json()
    this.user = users[Math.floor(Math.random() * users.length)]
  }
}

(async () {
  const user = new User()
  await user.promise
  return user
})().then(u => {
  $('#result').text(JSON.stringify(u.user, null, 2))
}).catch(err => {
  console.error(err)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre id="result"><code></code></pre>

于 2018-01-02T22:23:15.273 回答