web-dev-qa-db-ja.com

async / awaitをコンストラクターで使用できますか?

質問が述べたように。これを許可されますか?

class MyClass {
    async constructor(){
        return new Promise()
    }
}
23
wintercounter

将来の決定について占いをしようとせずに、実用性とすでに知られていることに集中しましょう。

ES7は、ES6と同様に、言語に対する下位互換性のある拡張を試みます。そのことを念頭に置いて、下位互換性のあるコンストラクター関数は、newキーワードで呼び出されることを意図した、基本的には通常の関数(実行時の制限付き)です。その場合、関数の戻り値は特別な扱いを受けます。具体的には、オブジェクト以外の戻り値は無視され、新しく割り当てられたオブジェクトが返されますが、オブジェクトの戻り値はそのまま返されます(新しく割り当てられたオブジェクトは破棄されます)。これを使用すると、コードによってプロミスが返され、「オブジェクトの構築」は行われません。これの実用性はわかりませんし、誰かが時間をかけてそのようなコードをどう処理するかを見つけると、拒否されると思います。

12
Amit

パトリックロバーツの発言をさらに詳しく説明するために、あなたが求めていることを行うことはできませんが、代わりに次のようなことを行うことができます。

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();
43
Dave P.

手短に:

  1. コンストラクタは、具象オブジェクトを提供する必要がある関数です。
  2. Asyncはpromiseを返します。具体性とは正反対です。
  3. async constructorは概念的に矛盾しています。
12
user900360

戻り値からpromiseを取得して、それを待つことができます。

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>
5
Benjamin Atkin