Quelles sont les différences entre le différé, la promesse et L'avenir dans JavaScript?

Quelles sont les différences entre Deferreds, des Promesses et des contrats à Terme?

Est-il généralement approuvé la théorie derrière ces trois-là?

281
demandé sur shA.t 2011-07-23 19:10:51

5 réponses

à la lumière de l'aversion apparente pour la façon dont j'ai tenté de répondre à la question de L'OP. La réponse littérale est, une promesse est quelque chose de partagé avec d'autres objets, tandis qu'un différé devrait être gardé privé. En premier lieu, une promesse différée (qui étend généralement la promesse) peut se résoudre d'elle-même, alors qu'une promesse pourrait ne pas être en mesure de le faire.

si vous êtes intéressé par les minutiae, alors examinez Promises/a+ .


Pour autant que je sache, le but primordial est d'améliorer la clarté et de desserrer le couplage à travers une interface standardisée. Voir suggestion de lecture de @jfriend00:

plutôt que de passer directement des callbacks à des fonctions, ce qui peut conduire à des interfaces étroitement couplées, en utilisant des promesses permet de préoccupations distinctes pour le code synchrone ou asynchrone.

personnellement, j'ai trouvé différé particulièrement utile lorsqu'il s'agit, par exemple, de gabarits qui sont remplis par des requêtes asynchrones, de chargements de scripts qui ont des réseaux de dépendances, et de fournir la rétroaction de l'utilisateur pour former des données de manière non-bloquante.

en effet, comparez la forme de rappel pure de faire quelque chose après avoir chargé CodeMirror en mode JS de façon asynchrone (excuses, je n'ai pas utilisé jQuery dans un tandis que ):

/* assume getScript has signature like: function (path, callback, context) 
   and listens to onload && onreadystatechange */
$(function () {
   getScript('path/to/CodeMirror', getJSMode);

   // onreadystate is not reliable for callback args.
   function getJSMode() {
       getScript('path/to/CodeMirror/mode/javascript/javascript.js', 
           ourAwesomeScript);
   };

   function ourAwesomeScript() {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   };
});

aux promesses formulé version (encore une fois, toutes mes excuses, je ne suis pas à jour sur jQuery):

/* Assume getScript returns a promise object */
$(function () {
   $.when(
       getScript('path/to/CodeMirror'),
       getScript('path/to/CodeMirror/mode/javascript/javascript.js')
   ).then(function () {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   });
});

toutes mes excuses pour le semi-pseudo code, mais j'espère que cela rend l'idée de base un peu claire. Fondamentalement, en retournant une promesse standardisée, vous pouvez transmettre la promesse autour, permettant ainsi un regroupement plus clair.

93
répondu fncomp 2018-10-04 17:42:24

ces réponses, y compris la réponse sélectionnée, sont bonnes pour introduire des promesses conceptuellement, mais manquant de détails sur ce que sont exactement les différences la terminologie qui se pose lors de l'utilisation de bibliothèques les mettant en œuvre (et il sont différences importantes).

Puisqu'il est toujours une spec évolutive , la réponse vient actuellement de tenter d'examiner les deux références (comme wikipedia ) et les implémentations (comme jQuery ):

  • différé : jamais décrit dans les références populaires, 1 2 3 4 mais couramment utilisé par les implémentations comme arbitre de résolution de promesse (implémentation de resolve et reject ). 5 6 7

    parfois, les reports sont aussi des promesses (implementing then ), 5 6 d'autres fois, il est considéré comme plus pur d'avoir le différé seulement capable de résolution, et forçant l'utilisateur à accéder à la promesse en utilisant then . 7

  • Promise : le mot qui englobe le plus la stratégie à l'étude.

    un objet proxy stockant le résultat d'une fonction cible dont synchronisation que nous aimerions abstraire, en plus d'exposer une fonction then accepter une autre fonction cible et retourner une nouvelle promesse. 2

    exemple de CommonJS :

    > asyncComputeTheAnswerToEverything()
        .then(addTwo)
        .then(printResult);
    44
    

    toujours décrit dans les références populaires, bien que jamais précisé dont la résolution relève de la responsabilité. 1 2 3 4

    toujours présent dans les implémentations populaires, et jamais donné la résolution des capacités. 5 6 7

  • futur : un terme apparemment déprécié trouvé dans certaines références populaires 1 et au moins une mise en œuvre populaire, 8 mais apparemment être éliminé de la discussion de préférence pour le terme "promesse" 3 et pas toujours mentionné dans les introductions sur le sujet. 9

    cependant, au moins une bibliothèque utilise le terme de façon générique pour synchronisation et traitement des erreurs, sans fournir la fonctionnalité then . 10 Il est difficile de savoir si d'éviter le terme "promesse" était intentionnel, mais probablement un bon choix puisque les promesses sont construites autour de " thenables.' 2

Références

  1. Wikipedia sur des Promesses Et des contrats à Terme
  2. Promesses/A+ spec
  3. DOM Standard Promesses
  4. DOM Standard Promises Spec WIP
  5. Dojo Toolkit Deferreeds
  6. jQuery Deferreeds
  7. Q
  8. FutureJS
  9. Fonctionnel section Javascript Promesses
  10. Futures dans L'intégration AngularJS Essai

Divers pouvant créer de la confusion des choses

137
répondu Woahdae 2014-03-07 19:30:27

ce qui a vraiment fait claquer tout ça pour moi était cette présentation de Domenic Denicola.

dans un GitHub gist , il a donné la description que j'aime le plus, il est très concis:

le but des promesses est de nous rendre la composition fonctionnelle et le bouillonnement d'erreur dans le monde asynchrone.

en d'autres termes, les promesses sont un moyen cela nous permet d'écrire asynchrone code qui est presque aussi facile à écrire que si elle était synchrone .

considérez cet exemple, avec des promesses:

getTweetsFor("domenic") // promise-returning async function
    .then(function (tweets) {
        var shortUrls = parseTweetsForUrls(tweets);
        var mostRecentShortUrl = shortUrls[0];
        return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function
    })
    .then(doHttpRequest) // promise-returning async function
    .then(
        function (responseBody) {
            console.log("Most recent link text:", responseBody);
        },
        function (error) {
            console.error("Error with the twitterverse:", error);
        }
    );

cela fonctionne comme si vous écriviez ce code synchrone:

try {
    var tweets = getTweetsFor("domenic"); // blocking
    var shortUrls = parseTweetsForUrls(tweets);
    var mostRecentShortUrl = shortUrls[0];
    var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2
    console.log("Most recent link text:", responseBody);
} catch (error) {
    console.error("Error with the twitterverse: ", error);
}

(si cela semble encore compliqué, regardez cette présentation!)

en ce qui concerne le différé, c'est un moyen de .resolve() ou .reject() les promesses. Dans le Promesses/B spec, il est appelé .defer() . À jQuery, c'est $.Deferred() .

s'il vous plaît noter que, pour autant que je sache, la mise en œuvre de la promesse dans jQuery est brisée (voir ce gist), au moins à partir de jQuery 1.8.2.

Il est supposé implémenter Promises / a thenables , mais vous ne recevez pas le traitement d'erreur correct vous devriez, dans le sens où le tout " async try / catch" la fonctionnalité ne marchera pas. Ce qui est dommage, car avoir un "try/catch" avec un code async est tout à fait cool.

Si vous allez utiliser des Promesses (vous devriez essayer avec votre propre code!), utilisez Q de Kris Kowal . La version jQuery est juste un agrégateur de callback pour écrire du code jQuery plus propre, mais manque le point.

en ce qui concerne le futur, je n'en ai aucune idée, Je ne l'ai vu dans aucune API.

Edit: Dominique Denicola youtube de parler de Promesses à partir de @la Ferme commentaire ci-dessous.

une citation de Michael Jackson (Oui, Michael Jackson ) de la vidéo:

je veux que vous brûliez cette phrase dans votre esprit: une promesse est une valeur asynchrone .

c'est une excellente description: Une promesse est comme une variable de l'avenir - une référence de première classe à quelque chose qui, à un moment donné, existera (ou arrivera).

70
répondu Camilo Martin 2017-05-23 10:31:14

A Promise représente une approximation d'une valeur qui n'est pas nécessairement connue lorsque la promesse est créée. Il vous permet d'associer les manipulateurs à la valeur de succès ou à la raison d'échec d'une action asynchrone. Cela permet aux méthodes asynchrones de retourner des valeurs comme les méthodes synchrones: au lieu de la valeur finale, la méthode asynchrone renvoie une promesse d'avoir une valeur à un moment donné dans le futur.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

la méthode deferred.promise() permet à une fonction asynchrone d'empêcher un autre code d'interférer avec la progression ou le statut de sa requête interne. La promesse n'expose que les méthodes différées nécessaires pour attacher des manipulateurs supplémentaires ou déterminer l'état ( puis, fait, fail, toujours, pipe, progrès, état et promesse ), mais pas ceux qui changent l'état ( résoudre, rejeter, notifier, résoudre avec, rejeter, et notifier avec ).

si la cible est fournie, deferred.promise() fixera les méthodes sur elle et retournera alors cet objet plutôt que d'en créer un nouveau. Cela peut être utile pour attacher le comportement de promesse à un objet qui existe déjà.

si vous créez un différé, conservez une référence au différé afin qu'il puisse être résolu ou rejeté à un moment donné. Retourner seulement L'objet de la promesse via différé.promise () pour que d'autres codes puissent enregistrer des callbacks ou inspecter l'état actuel.

Simplement, nous pouvons dire qu'un Promesse représente une valeur qui n'est pas encore connu où, comme un Différé", 151940920" représente le travail qui n'est pas encore terminée.


enter image description here

24
répondu IRSHAD 2018-03-01 07:23:28
  • Un promise représente une valeur qui n'est pas encore connue
  • A deferred représente un travail qui n'est pas encore terminé

une promesse est un conteneur pour un résultat qui est initialement inconnu alors qu'un différé représente le calcul qui aboutit à la valeur.

référence

20
répondu mattLummus 2016-04-05 08:28:09