J'utilise ES6 Promise.
Normalement, une promesse est construite et utilisée comme ceci
new Promise(function(resolve, reject){
if (someCondition){
resolve();
} else {
reject();
}
});
Mais j'ai fait quelque chose comme ci-dessous pour prendre la résolution à l'extérieur par souci de flexibilité.
var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) {
outsideResolve = resolve;
outsideReject = reject;
});
Et ensuite
onClick = function(){
outsideResolve();
}
Cela fonctionne bien, mais existe-t-il un moyen plus simple de le faire? Sinon, est-ce une bonne pratique?
Promise
doit être exécuté de manière synchrone pour permettre "d'exporter" les deux fonctions.Réponses:
Non, il n'y a pas d'autre moyen de le faire - la seule chose que je peux dire, c'est que ce cas d'utilisation n'est pas très courant. Comme Felix l'a dit dans le commentaire - ce que vous faites fonctionnera toujours.
Il convient de mentionner que la raison pour laquelle le constructeur de promesses se comporte de cette façon est la sécurité des lancers - si une exception que vous ne pensiez pas se produit pendant que votre code s'exécute à l'intérieur du constructeur de promesses, cela se transformera en rejet, cette forme de sécurité des lancers - conversion des erreurs levées en les rejets sont importants et aident à maintenir un code prévisible.
Pour cette raison de sécurité, le constructeur de promesse a été choisi parmi les différés (qui sont une autre façon de construire la promesse qui permet ce que vous faites) - comme pour les meilleures pratiques - je passerais l'élément et utiliserais plutôt le constructeur de promesse:
Pour cette raison - chaque fois que vous pouvez utiliser le constructeur de promesses plutôt que d'exporter les fonctions - je vous recommande de l'utiliser. Chaque fois que vous pouvez éviter les deux - évitez les deux et la chaîne.
Notez que vous ne devriez jamais utiliser le constructeur de promesses pour des choses comme
if(condition)
, le premier exemple pourrait être écrit comme suit:la source
Promise
chaîne? Par exemple, dans mon cas particulier, je suis sur un serveur, en attente d'une réponse spécifique du client (une poignée de main SYN-ACK-kinda pour vous assurer que le client est correctement mis à jour).Facile:
la source
promiseResolve()
. La sémantique d'une promesse est qu'elle renvoie toujours une valeur. De plus, c'est la même chose que la publication de OP, je ne comprends pas quel problème cela résout de manière réutilisable.promiseResolve()
ne lèvera pas d'exception. Vous pouvez définir un.catch
sur le constructeur et quel que soit le code qui l'appelle, le constructeur.catch
sera appelé. Voici le jsbin montrant comment cela fonctionne: jsbin.com/yicerewivo/edit?js,consoleUn peu tard pour la fête ici, mais une autre façon de le faire serait d'utiliser un objet différé . Vous avez essentiellement la même quantité de passe-partout, mais c'est pratique si vous voulez les faire circuler et éventuellement résoudre en dehors de leur définition.
Implémentation naïve:
Version ES5:
la source
resolve|reject
leur attribution lexicale ou à traversbind
. Il s'agit simplement d'une implémentation simple de l' objet jQuery Deferred qui existe depuis 1.0 (ish). Cela fonctionne exactement comme une promesse, sauf qu'il n'y a pas de sécurité contre les lancers. L'intérêt de cette question était de savoir comment enregistrer quelques lignes de code lors de la création de promesses.Deferred
obsolète?Une solution que j'ai trouvée en 2015 pour mon framework. J'ai appelé ce type de promesses Tâche
la source
J'ai aimé la réponse @JonJaques mais je voulais aller plus loin.
Si vous liez
then
etcatch
ensuite l'Deferred
objet, il met pleinement en œuvre l'Promise
API et vous pouvez le traiter comme promesse etawait
et tel.la source
Une méthode d'assistance atténuerait cette surcharge supplémentaire et vous donnerait la même sensation jQuery.
L'utilisation serait
Qui est similaire à jQuery
Bien que, dans un cas d'utilisation, cette syntaxe simple et native soit correcte
la source
J'utilise une fonction d'aide pour créer ce que j'appelle une "promesse plate" -
Et je l'utilise comme ça -
Voir l'exemple de travail complet -
Afficher l'extrait de code
Edit: J'ai créé un package NPM appelé flat-promise et le code est également disponible sur GitHub .
la source
Vous pouvez envelopper la promesse dans une classe.
la source
La plupart des réponses ici sont similaires au dernier exemple de cet article . Je mets en cache plusieurs promesses, et les fonctions
resolve()
etreject()
peuvent être affectées à n'importe quelle variable ou propriété. En conséquence, je suis en mesure de rendre ce code légèrement plus compact:Voici un exemple simplifié d'utilisation de cette version de
defer()
pour combiner uneFontFace
promesse de chargement avec un autre processus asynchrone:Mise à jour: 2 alternatives au cas où vous souhaitez encapsuler l'objet:
et
la source
const result = await deferred.promise;
La réponse acceptée est fausse. Il est assez facile d'utiliser la portée et les références, bien que cela puisse mettre les puristes de Promise en colère:
Nous saisissons essentiellement la référence à la fonction de résolution lorsque la promesse est créée, et nous la renvoyons pour qu'elle puisse être définie en externe.
En une seconde, la console affichera:
la source
Oui, vous pouvez. En utilisant l'
CustomEvent
API pour l'environnement du navigateur. Et en utilisant un projet d'émetteur d'événements dans les environnements node.js. Étant donné que l'extrait de code de la question concerne l'environnement du navigateur, voici un exemple de travail pour le même.J'espère que cette réponse est utile!
la source
Notre solution consistait à utiliser des fermetures pour stocker les fonctions de résolution / rejet et à attacher en plus une fonction pour étendre la promesse elle-même.
Voici le schéma:
Et en l'utilisant:
la source
promise.resolve_ex = _resolve; promise.reject_ex = _reject;
... fonctionne toujours bien.Je me retrouve également à manquer le schéma différé dans certains cas. Vous pouvez toujours en créer un en plus d'une promesse ES6:
la source
Merci à tous ceux qui ont posté dans ce fil. J'ai créé un module qui inclut l'objet Defer () décrit précédemment ainsi que quelques autres objets construits sur lui. Ils utilisent tous Promises et la syntaxe de rappel Promise pour implémenter la communication / la gestion des événements dans un programme.
File d'attente: file d'attente d'exécution basée sur le chaînage Promise.
rp = require("repeatable-promise")
https://github.com/CABrouwers/repeatable-promise
la source
J'ai écrit une petite lib pour ça. https://www.npmjs.com/package/@inf3rno/promise.exposed
Je l'approche d' autres méthode de l' usine ont écrit, mais je l' emportaient sur le
then
,catch
, lesfinally
méthodes aussi, vous pouvez donc résoudre la promesse originelle de ceux aussi bien.Résoudre la promesse sans exécuteur testamentaire de l'extérieur:
Course avec setTimeout de l'exécutif de l'extérieur:
Il existe un mode sans conflit si vous ne voulez pas polluer l'espace de noms global:
la source
J'ai créé une bibliothèque appelée
manual-promise
qui fonctionne en remplacement dePromise
. Aucune des autres réponses ici ne fonctionnera comme remplacement de remplacement pourPromise
, car elles utilisent des proxy ou des wrappers.yarn add manual-promise
npn install manual-promise
https://github.com/zpxp/manual-promise#readme
la source
Que diriez-vous de créer une fonction pour détourner le rejet et le renvoyer?
la source
J'ai mis en place un résumé qui fait ce travail: https://gist.github.com/thiagoh/c24310b562d50a14f3e7602a82b4ef13
voici comment l'utiliser:
la source
activer d'abord --allow-natives-syntax sur le navigateur ou le nœud
la source
Juste une autre solution pour résoudre Promise de l'extérieur
Usage
la source