Sont JavaScript ES6 Classes de toute utilisation avec le code asynchrone bases?
Ce qui peut ES6 Classes 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.
- vous pouviez retourner une promesse du constructeur qui se résout avec l'instance vous donnant ainsi accès à l'instance une fois qu'il est initialisé.
- la pensée ne se produire pour moi, mais il semble horrible.
- Je n'aime pas particulièrement non plus, mais... quel autre moyen y aurait-il? il y a un rappel de quelque part, c'est soit d'aller à une promesse ou d'un callback passé en paramètre. async/await a encore un rappel, vous n'avez tout simplement pas le voir.
- Je pense que vous avez raison, je pense que les Classes ne sont qu'un bientôt-à-être anti-modèle. D'entrer dans avec un asychronous base de code va être très difficile de sortir d'écrire vraiment utile bibliothèques asynchrones va être très difficile, et de la prospective de l'appelant, il va être extrêmement difficile à écrire,
await new Foo(url);
j'ai fait de la question plus vaste, et je ne veux pas supposer que je connais la réponse. Nous allons attendre et voir si quelqu'un les tambours de quoi que ce soit d'autre. Si pas, je vais bounty il.
Vous devez vous connecter pour publier un commentaire.
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.Un tel constructeur ne devrait pas exister du tout, voir C'est une mauvaise pratique d'avoir un constructeur de retour de la fonction une Promesse?
Oui, vous pouvez utiliser des méthodes asynchrones (même avec le projet de
async
syntaxe) sur les classes et les méthodes de lecture peut retourner promet ainsi.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.
class
syntaxe n'apporte rien de nouveau sur la table, asynchronisme et de l'état des objets (instances) a toujours été compliqué.class Foo { constructor(input) { return new Promise(resolve => resolve(input)); } } new Foo('bar').then(res => console.log(res))
Une autre façon que les Classes peut être utile pour organiser les tâches asynchrones est à l'usage exclusif de méthodes statiques.
Bien sûr, ce n'est pas différent que de créer un objet simple, littérale ou un nouveau fichier et y compris, sauf que vous pouvez plus proprement
extend
il.Object.create
etObject.assign
). Ou, compte tenu de ES6 modules, il suffit d'utiliser de multiples nommé par les exportations, l'extension de celles-ci est encore plus facile, c'est comme parasite de l'héritage.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 async/await est que des erreurs de la bulle jusqu'implicitement
Si elle est limitée à ECMAScript 2015 et pas async, retour promesse de des valeurs:
Ce 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 avez vraiment, vraiment envie d'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.
Toutes les promesses besoin d'une prise finale ou il y aura de la difficulté à
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 dePromise.prototype.then()
, lexicalesthis
à l'intérieur de la fonction est la fonction elle-même, et non pas la classe. C'est pourquoi lesthis.res
semble ne rien faire:this
, dans ce cas, se réfère à la fonction propre champ d'application.Il y a 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) étant:
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 flèche fonctions, qui n'est pas de créer un nouveau champ d'application, mais plutôt à "garder" l'actuel.
De côté à partir du 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 uneasync constructor () { ... }
, vous pouvez lancer une promesse dans le constructeur, etawait
dans les fonctions qui en dépendent.Exemple gist d'une propriété async dans un constructeur de classe.