Comment extraire des données d'une Promesse
J'ai une promesse qui renvoie des données et je veux enregistrer dans des variables. Est-ce impossible en JavaScript en raison de la nature asynchrone et dois-je l'utiliser onResolve
comme un rappel?
Je peux en quelque sorte l'utiliser (par exemple, envelopper avec async/await):
const { foo, bar } = Promise.then(result => result.data, errorHandler);
//rest of script
au lieu de cela?
Promise.then(result => {
const { foo, bar } = result.data;
//rest of script
}, errorHandler);
Remarque: Bluebird bibliothèque est utilisée à la place de l'implémentation native, et je ne peux pas changer la Promesse de asnyc/attendre ou des Générateurs.
C'est possible avec javascript. Vous pouvez affecter les données que vous recevez sur la promesse de succès à la variable à laquelle vous avez déclaré plus tôt. Et votre variable ont que la valeur que vous avez reçu de promesse. Vous pouvez vous référer: developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
C'est possible, mais peut causer des bugs que JavaScript ne pas attendre la Promesse à résoudre. Aussi besoin de changer
Juste pour info,
Cette syntaxe fonctionne bien avec la bluebird.js la mise en œuvre. Voir bluebird référence de l'API ici C'est aussi correct d'après Promesses/A+ norme (voir le paragraphe 2.2)
async/ await
sont à venir!C'est possible, mais peut causer des bugs que JavaScript ne pas attendre la Promesse à résoudre. Aussi besoin de changer
const
à let
, ce qui peut avoir des effets secondaires.Juste pour info,
errorHandler
n'a pas vraiment gérer une erreur ici, c'est juste exécute immédiatementCette syntaxe fonctionne bien avec la bluebird.js la mise en œuvre. Voir bluebird référence de l'API ici C'est aussi correct d'après Promesses/A+ norme (voir le paragraphe 2.2)
OriginalL'auteur Tobias Mühl | 2016-04-28
Vous devez vous connecter pour publier un commentaire.
NON vous ne pouvez pas obtenir les données de façon synchrone d'une promesse, comme vous le suggérez dans votre exemple. Les données doivent être utilisés dans une fonction de rappel. Sinon dans la programmation fonctionnelle style de la promesse de données pourrait être map()ed plus.
Si vous êtes OK à l'aide de async/await (c'est génial), alors vous pouvez écrire du code qui ressemble synchrone encore conserver l'asynchronicité d'une promesse (voir @loganfsmyth commentaires).
Globale puisque vous êtes déjà à l'aide de ES6 je suppose que vous êtes aussi à l'aide d'un transpiler. Dans ce cas, vous devriez certainement donner async/await un essai.
Juste être sûr de poids dans la décision que, comme aujourd'hui, ils ne sont pas encore ratifié la spécification.
En aval, le code dans le gestionnaire habitude de l'exécuter, mais le fil sera libéré non le moins. Donc, navigateur habitude de congeler. Maintenant, si une fonction utilise
await
à son meilleur niveau, mais l'aval de code n'est autre opération qui ne nécessite pas les données retournées par leasync
fonction, alors c'est une erreur de conception.Ce qui rend le navigateur gel si le thread est bloqué par le fonctionnement synchrone. Qui n'arrive pas avec
async/await
plus qu'il ne le fait avec un rappel. Comme vous l'avez dit c'est juste un peu de sucre mais derrière la scène, il fonctionne de la même façon.Vous vous êtes trompé, async/await ne bloque pas, il exécutera la fonction async jusqu'à la première
await
et puis, suspendre l'exécution de la fonction async et de contrôle de retour à la portée parent et le retour d'une promesse. Lorsque la valeur passée à attendre est disponible, l'exécution de la fonction va reprendre. Il y a une différence importante entre le blocage et la suspension de l'exécution.Honte sur moi. Je viens de réaliser que j'ai oublié un point important: Vous ne pouvez
await
dans async fonctions. J'ai eu régulièrement des fonctions à l'esprit, ce qui serait synchrone et, par conséquent, serait de les bloquer.OriginalL'auteur silkAdmin
Alors que vous pouvez obtenir une valeur à partir d'un attendu Promesse à l'intérieur d'une fonction async (tout simplement parce qu'il interrompt la fonction d'attendre un résultat), vous ne pouvez pas toujours obtenir directement une valeur d'une Promesse et à l'arrière dans le même champ d'application que la Promesse elle-même.
C'est parce que "hors de" signifierait essayer de prendre quelque chose qui existe dans l'avenir (l'a finalement résolu valeur) et de le mettre dans un cadre (synchrone affectation de variable) qui déjà arrivé dans le passé.
Qui est, à voyager dans le temps. Et même si le voyage dans le temps était possible, il ne serait probablement pas une bonne pratique de codage, parce que le temps de voyage peut être très déroutant.:)
En général, si vous vous sentez comme vous avez besoin de faire cela, c'est bon signe que vous avez besoin de revoir quelque chose. Notez que ce que vous faites avec "résultat => résultat.les données" ici:
..est déjà un cas de ce que vous travaillez avec (littéralement, la cartographie sur) la valeur en la passant à une fonction. Mais, en supposant que "//reste du script" ne quelque chose d'important lié à cette valeur, vous voulez probablement continuer cartographier le présent mise à jour de la valeur avec encore une autre fonction qui puis quelque chose d'effets secondaires-y avec la valeur (comme l'affichage des données sur l'écran).
"doSomethingWithData" sera appelé (si il ne l'a jamais appelé) à un point inconnu dans l'avenir. C'est pourquoi il est une bonne pratique pour clairement encapsuler tous que le comportement dans une fonction spécifique, puis accrocher cette fonction jusqu'à la Promesse de la chaîne.
C'est honnêtement mieux de cette façon, parce qu'il vous oblige à déclarer clairement une séquence particulière d'événements qui sera arriver, explicitement séparées de la première course à travers tout le code de votre application à l'exécution.
Pour le dire d'une autre façon, imaginez ce scénario, hypothétiquement exécuté dans le global, de haut niveau portée:
Qu'attendez-vous pour y arriver? Il y a deux possibilités, et deux d'entre eux sont mauvais.
avant qu'il puisse savoir quels sont les "foo" & "bar"... non, pourrait être. (c'est
ce qui "attendent" à l'intérieur d'une fonction async, en fait: il s'arrête
l'intégralité de la fonction d'exécution jusqu'à ce que la valeur n'est disponible, ou une erreur est renvoyée)
arrive), puisque, comme l'a exécuté de manière synchrone, ils venaient tout juste d'être
inexistante propriétés de haut niveau de la Promesse de l'objet (qui n'est pas elle-même une "valeur",
mais plutôt une quasi-Monadique wrapper autour de arriver une éventuelle valeur OU une erreur) qui la plupart
probablement n'est pas même contenir une valeur encore.
OriginalL'auteur Dtipson