web-dev-qa-db-fra.com

Async / Wait peut-il être utilisé dans les constructeurs?

Comme l'indique la question. Serai-je autorisé à faire ceci:

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

Sans essayer de dire la fortune des décisions futures, concentrons-nous sur l'aspect pratique et ce qui est déjà connu.

ES7, comme ES6 avant, il essaiera d'être une extension rétrocompatible de la langue. Dans cet esprit, une fonction constructeur rétrocompatible est essentiellement une fonction régulière (avec certaines restrictions d'exécution) qui est destinée à être invoquée avec le mot clé new. Lorsque cela se produit, la valeur de retour de la fonction reçoit un traitement spécial, en particulier, les valeurs de retour non-objet sont ignorées et l'objet nouvellement alloué est retourné tandis que les valeurs de retour d'objet sont retournées telles quelles (et l'objet nouvellement alloué est jeté). Avec cela, votre code entraînerait le retour d'une promesse et aucune "construction d'objet" n'aurait lieu. Je ne vois pas le caractère pratique de cela et je suppose que si quelqu'un prend le temps de trouver quoi faire avec un tel code, il sera rejeté.

12
Amit

Pour développer ce que Patrick Roberts a dit, vous ne pouvez pas faire ce que vous demandez, mais vous pouvez faire quelque chose comme ceci à la place:

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

  async initialize() {
     await WhatEverYouWant();
  }

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

Ensuite, dans votre code, créez votre objet comme ceci:

const obj = await MyClass.create();
43
Dave P.

En un mot:

  1. Le constructeur est une fonction qui doit fournir un objet concret.
  2. Async renvoie une promesse; exactement à l'opposé du concret.
  3. async constructor est conceptuellement conflictuel.
12
user900360

Vous pouvez obtenir une promesse de la valeur de retour et attendre:

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