web-dev-qa-db-fra.com

JavaScript asynchrone - rappels vs différé / promesse

Duplicata possible:
Quelles sont les différences entre différé, promis et futur en Javascript?

Dernièrement, j'ai fait un effort pour améliorer la qualité de mes applications JavaScript.

Un modèle que j'ai adopté consiste à utiliser un objet "contexte de données" distinct pour charger les données de mon application (auparavant, je faisais cela directement dans mes modèles de vue).

L'exemple suivant renvoie des données initialisées sur le client:

var mockData = (function($, undefined) {

    var fruit = [
        "Apple",
        "orange",
        "banana",
        "pear"
        ];

    var getFruit = function() {
        return fruit;
    };

    return {
        getFruit: getFruit
    }
})(jQuery);

Dans la plupart des cas, nous chargerons des données à partir du serveur, nous ne pourrons donc pas retourner de réponse immédiate. Il semble que j'ai deux options sur la façon dont nous traitons cela dans notre API:

  1. Utiliser un rappel
  2. Renvoyer un promesse .

Auparavant, j'avais toujours utilisé l'approche de rappel:

var getFruit = function(onFruitReady) {
    onFruitReady(fruit);
};

// ...

var FruitModel = function(dataContext, $) {
    return {
        render: function() {
            dataContext.getFruit(function(fruit) {
                // do something with fruit
            });
        }
    };
};

Cependant, je peux voir comment il est possible de se retrouver dans l'enfer des rappels, en particulier lors de la création d'applications JavaScript complexes.

Puis je suis tombé sur le modèle de conception Promises. Au lieu d'exiger que l'appelant fournisse un rappel, je renvoie plutôt une "promesse" qui peut être observée:

var getFruit = function() {
    return $.Deferred().resolve(fruit).promise();
};

// ...
dataContext.getFruit().then(function(fruit) {
    // do something with fruit
});

Je peux voir les avantages évidents de l'utilisation de ce modèle, d'autant plus que je peux wait sur plusieurs objets différés qui pourraient être très utiles lors du chargement des données d'initialisation pour une application d'une seule page.

Cependant, je tiens à comprendre les avantages et les inconvénients de chaque modèle avant de commencer à utiliser l'un ou l'autre en colère. Je suis également intéressé de savoir si c'est la direction dans laquelle d'autres bibliothèques vont. Cela semble être le cas avec jQuery.

Voici un lien vers le violon que j'utilise pour les tests.

51
Ben Foster

Les promesses reposent également sur des rappels dans les coulisses, donc ce n'est pas vraiment l'un contre l'autre.

L'avantage des rappels est qu'ils sont faciles à implémenter avec du JavaScript simple (par exemple dans les appels ajax).

Les promesses nécessitent une couche d'abstraction supplémentaire, ce qui signifie généralement que vous vous reposerez sur une bibliothèque (pas un problème dans votre cas car vous utilisez déjà jQuery). Ils sont parfaits lorsque vous traitez plusieurs appels asynchrones en parallèle.

18
Christophe

En lisant les documents jQuery auxquels @Pointy est lié, il semble que la différence est que l'API différée vous permet de spécifier plus d'une fonction à appeler lorsque votre demande se termine:

À partir de jQuery 1.5, les hooks de rappel d'erreur (échec), de réussite (terminé) et complet (toujours, à partir de jQuery 1.6) sont des files d'attente gérées de premier entré, premier sorti. Cela signifie que vous pouvez attribuer plusieurs rappels pour chaque hook. Voir Méthodes d'objet différé, qui sont implémentées en interne pour ces hooks de rappel $ .ajax ().

Voir aussi: deferred.then ()

3
Max Fellows