59 votes

Les classes JavaScript ES6 sont-elles d’une quelconque utilité avec les bases de code asynchrones?

Que peut - ES6 Classes de fournir, comme un modèle d'organisation, de code asynchrone. Ci-dessous un exemple avec ES7 async/await, peut-ES6-classe ont une méthode asynchrone, ou d'un constructeur dans l'ES7?

Puis-je faire:

class Foo {
    async constructor() {
        let res = await getHTML();
        this.res = res
    }
}

Et, si non comment un constructeur de travail qui fait cela?

class Foo {
    constructor() {
        getHTML().then( function (res) {
            this.res = res
        }
    }
}

Si aucune de ces habitudes de travail, un constructeur (et d'ailleurs classes) dans un ES6 class soutenir toute forme de l'asynchronicité qui fonctionne sur l'état de l'objet? Ou, sont-ils uniquement à des fins purement synchrone bases de code? Les exemples ci-dessus sont dans le constructeur, mais ils n'ont pas besoin d'être.. en Poussant le problème à un autre niveau..

class Foo {
    myMethod () {
      /* Can I do anything async here */
    }
}

Ou, avec un getter...

class Foo {
    get myProp() {
        /* Is there any case that this is usefully asynchronous */
    }
}

Les seuls exemples que je pouvais penser est de lancer quelque chose en parallèle à l'intérieur de la même méthode/constructeur/getter, mais de l'ensemble de la chose résoudre avant la conclusion. Je suis juste confus parce qu'il semble avec tous les pousser à totalement asynchrones bibliothèques, cela sert juste à confondre les choses. Sauf pour les exemples classiques, je ne peux pas trouver une application utile pour.

51voto

Bergi Points 104242

Puis-je faire async constructor()

Non, c'est une erreur de syntaxe - tout comme constructor* (). Un constructeur est une méthode qui ne retourne rien (pas de promesse, pas de générateur), il ne s'initialise l'instance.

Et, si non comment un constructeur de travail qui fait cela

Tel un constructeur ne devrait pas exister du tout, voir Est-il une mauvaise pratique d'avoir un constructeur de retour de la fonction une Promesse?

Peut ES6 classes de soutenir toute forme d'asynchronie qui fonctionne sur l'état de l'objet? Ou, sont-ils uniquement à des fins purement synchrone bases de code?

Oui, vous pouvez utiliser des méthodes asynchrones (même avec le projet de async de la syntaxe) sur les classes et les méthodes de lecture peut retourner promesses.

Toutefois, vous aurez besoin de décider ce qui doit se produire lorsqu'une méthode est appelée lors de certains processus asynchrone est toujours actif. Si vous souhaitez que la séquence de l'ensemble de vos opérations, vous devez stocker l'état de votre instance à l'intérieur d'une promesse de la fin de la séquence que vous pouvez enchaîner sur. Ou, si vous souhaitez autoriser les opérations en parallèle, la meilleure approche est de prendre votre cas immuable et retourner une promesse pour une autre instance.

12voto

Evan Carroll Points 13420

Les classes peuvent également être utiles pour organiser des tâches asynchrones grâce à l'utilisation exclusive de méthodes statiques .

 class Organizer {
    static async foo() {
        const data = await this.bar();
        data.key = value;
        return data;
    }
    static async bar() {
        return {foo:1, bar:2}
    }
};

Organizer.foo();
 

Bien sûr, cela n’est pas différent de la création d’un littéral d’objet simple, ou d’un nouveau fichier et de l’inclusion de ce dernier, à moins que vous ne puissiez plus proprement le extend .

11voto

Harald Rudell Points 329

ECMAScript 2017 est destiné à être classes de méthodes asynchrones.

En invoquant un autre async ou de la promesse-de retour de la fonction est un one-liner!

Le très expressif code lit sans interruption du haut vers le bas, indépendamment de l'exécution différée

Si vous avez des rappels, alternative gestionnaires d'erreur, l'exécution en parallèle ou d'autres besoins non satisfaits, instancier des promesses dans le corps de la fonction. Il est préférable d'avoir le code dans le corps de la fonction, plutôt que dans une promesse d'exécuteur testamentaire, et remarque qu'il n'y a pas de try-catch emballage de rappel code: do suivante à rien.

La méthode asynchrone peut retourner une promesse, une valeur, ou de jeter

Le rappel des api qui Node.js les gens de l'amour, nous allons maintenant de la haine avec une passion: ils doivent tous être enveloppé dans les promesses de

La beauté de la async/await est que des erreurs de la bulle jusqu'implicitement

class MyClass {
  async doEverything() {
    const sumOfItAll = await http.scrapeTheInternet() +
      await new Promise((resolve, reject) =>
        http.asyncCallback((e, result) => !e ? resolve(result) : reject(e)))
    return this.resp = sumOfItAll
  }
}

Si elle est limitée à ECMAScript 2015 et pas async, retour promesse de des valeurs:

class ES2015 {
  fetch(url) {
    return new Promise((resolve, reject) =>
      http.get(url, resolve).on('error', reject))
      .then(resp => this.resp = resp) // plain ECMAScript stores result
      .catch(e => { // optional internal error handler
        console.error(e.message)
        throw e // if errors should propagate
      })
  }
}

Cette ECMAScript version de 2015 est ce que vous êtes vraiment se demander à propos, tout comportement désiré peut être codé en utilisant le retourné promesse de construire.

Si vous voulez vraiment, vraiment exécuter des promesses dans le constructeur, c'est une bonne idée de passer dans le catch fonctions ou de fournir certains de rappel de construire, de sorte que les consommateurs puissent prendre des mesures sur la promesse de l'accomplissement ou de rejet. Dans le constructeur, il est également judicieux d'attendre nextTick/.puis avant de faire un réel travail.

Chaque promesse besoin d'une prise finale ou il y aura des problèmes

0voto

Christophe Marois Points 705

C'est une réponse tardive, mais la raison de votre deuxième exemple ne fonctionne pas en raison du contexte de l'erreur. Lorsque vous passez une function () {} comme un argument à l' Promise.prototype.then(), lexicales this à l'intérieur de la fonction est la fonction elle-même, et non pas la classe. C'est pourquoi le paramètre this.res semble ne rien faire: this, dans ce cas, se réfère à la fonction propre champ d'application.

Il existe plusieurs façons d'accéder à l'extérieur de la portée en Javascript, le classique (que vous voyez en abondance dans ES5 code):

class Foo {
  constructor() {
    var _this = this

    getHTML().then(function (res) {
      _this.res = res
    })
  }
}

En faisant une référence à la classe this, vous pouvez y accéder de l'intérieur étendues.

L'ES6 façon de le faire est d'utiliser la flèche fonctionsqui ne sont pas de créer un nouveau champ d'application, mais plutôt à "garder" l'actuel.

class Foo {
  constructor() {
    getHTML().then(res => this.res = res)
  }
}

Hormis le contexte des préoccupations, ce n'est pas encore optimale du modèle asynchrone à mon avis, parce que vous avez aucun moyen de savoir quand getHTML() a fini, ou pire, a échoué. Ce problème est résolu avec élégance avec async fonctions. Si vous ne pouvez pas faire une async constructor () { ... }, vous pouvez lancer une promesse dans le constructeur, et await dans les fonctions qui en dépendent.

Exemple de résumé d'une propriété async dans un constructeur de classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X