web-dev-qa-db-fra.com

Pourquoi les rappels sont-ils plus "étroitement couplés" que les promesses?

Pouvez-vous m'expliquer la phrase suivante (tirée de ne réponse à la question Stack Overflow Quelles sont les différences entre différé, promis et futur en Javascript? )?

Quels sont les avantages de l'utilisation de jQuery promesses contre l'utilisation des rappels jQuery précédents?

Plutôt que de passer directement des rappels à des fonctions, ce qui peut conduire à des interfaces étroitement couplées, l'utilisation de promesses permet de séparer les problèmes de code synchrone ou asynchrone.

36
Revious

Je ne pense pas que les promesses soient plus ou moins couplées que les rappels, à peu près la même chose.

Les promesses ont cependant d'autres avantages:

  • Si vous exposez un rappel, vous devez documenter s'il sera appelé une fois (comme dans jQuery.ajax) ou plus d'une fois (comme dans Array.map). Les promesses sont appelées toujours une fois.

  • Il n'y a aucun moyen d'appeler un rappel et une exception, vous devez donc fournir un autre rappel pour le cas d'erreur.

  • Un seul rappel peut être enregistré, plus d'un pour les promesses, et vous pouvez les enregistrer APRÈS l'événement et vous serez de toute façon appelé.

  • Dans une déclaration typée (TypeScript), Promise facilite la lecture de la signature.

  • À l'avenir, vous pourrez profiter d'une syntaxe asynchrone/rendement.

  • Parce qu'ils sont standard, vous pouvez créer des composants réutilisables comme celui-ci:

     disableScreen<T>(promiseGenerator: () => Promise<T>) : Promise<T>
     {
         //create transparent div
         return promiseGenerator.then(val=>
         {
            //remove transparent div
            return val;
         }, error=>{
             //remove transparent div
             throw error;
         });
     }
    
     disableScreen(()=>$.ajax(....));
    

Plus d'informations à ce sujet: http://www.html5rocks.com/en/tutorials/es6/promises/

MODIFIER:

  • Un autre avantage est l'écriture d'une séquence de N appels asynchrones sans N niveaux d'indentation.

De plus, même si je ne pense toujours pas que ce soit le point principal, maintenant je pense qu'ils sont un peu plus lâchement couplés pour ces raisons:

  • Ils sont standard (ou du moins essayez): le code en C # ou Java qui utilise des chaînes est plus moche que le code similaire en C++, car les différentes implémentations de chaînes là-bas, le rendant plus réutilisable. Ayant une promesse standard, l'appelant et l'implémentation sont moins couplés car ils n'ont pas à se mettre d'accord sur une (paire) de rappels personnalisés avec des ordres de paramètres personnalisés, des noms, etc ... Le fait qu'il existe de nombreux différents les saveurs sur les promesses n'aident pas la pensée.

  • Ils favorisent une programmation plus basée sur l'expression, plus facile à composer, à mettre en cache, etc.:

      var cache: { [key: string] : Promise<any> };
    
      function getData(key: string): Promise<any> {
          return cache[key] || (cache[key] = getFromServer(key)); 
      }
    

vous pouvez affirmer que la programmation basée sur l'expression est plus faiblement couplée que la programmation basée sur l'impératif/le rappel, ou du moins ils poursuivent le même objectif: la composabilité.

12
Olmo

ne promesse est un objet qui représente le résultat d'une opération asynchrone , et à cause de cela vous pouvez le faire circuler, et cela vous donne plus de flexibilité.

Si vous utilisez un rappel, au moment de l'appel de l'opération asynchrone, vous devez spécifier comment il sera géré, d'où le couplage. Avec des promesses, vous pouvez spécifier comment il sera traité plus tard.

Voici un exemple, imaginez que vous souhaitez charger des données via ajax et que vous souhaitez afficher une page de chargement.

Avec rappels:

void loadData = function(){
  showLoadingScreen();
  $.ajax("http://someurl.com", {
    complete: function(data){
      hideLoadingScreen();
      //do something with the data
    }
  });
};

Le rappel qui gère les données qui reviennent doit appeler hideLoadingScreen.

Avec des promesses, vous pouvez réécrire l'extrait ci-dessus afin qu'il devienne plus lisible et que vous n'ayez pas à mettre le hideLoadingScreen dans le rappel complet.

Avec des promesses

var getData = function(){
  showLoadingScreen();
  return $.ajax("http://someurl.com").promise().always(hideLoadingScreen);
};

var loadData = function(){
  var gettingData = getData();
  gettingData.done(doSomethingWithTheData);
}

var doSomethingWithTheData = function(data){
 //do something with data
};

MISE À JOUR: J'ai écrit un article de blog qui fournit des exemples supplémentaires et fournit une description claire de ce qu'est une promesse et comment son utilisation peut être comparée à l'utilisation de rappels.

50
Rui

Le couplage est plus lâche avec des promesses car l'opération n'a pas à "savoir" comment elle continue, elle n'a qu'à savoir quand elle est prête.

Lorsque vous utilisez des rappels, l'opération asynchrone a en fait une référence à sa continuation, ce qui n'est pas son affaire.

Avec des promesses, vous pouvez facilement créer une expression sur une opération asynchrone avant même de décider comment elle va se résoudre.

Les promesses aident donc à séparer les préoccupations de l'enchaînement des événements par rapport au travail réel.

27
harpo

Les promesses réifient le concept de réponse retardée à quelque chose. Ils font du calcul asynchrone un citoyen de première classe car vous pouvez le faire circuler. Ils vous permettent de définir la structure si vous le souhaitez - c'est-à-dire la structure monadique - sur laquelle vous pouvez construire des combinateurs d'ordre supérieur qui simplifient considérablement le code.

Par exemple, vous pouvez avoir une fonction qui prend un tableau de promesses et retourne une promesse d'un tableau (généralement cela s'appelle sequence). C'est très difficile à faire ou même impossible avec les rappels. Et ces combinateurs ne facilitent pas seulement l'écriture du code, ils le rendent beaucoup plus facile à lire.

Considérez maintenant l'inverse pour répondre à votre question. Les rappels sont une solution ad hoc où les promesses permettent une structure plus claire et une réutilisation.

5
edofic

Ce n'est pas le cas, c'est juste une rationalisation que les gens qui manquent complètement au point de promesse utilisent pour justifier l'écriture de beaucoup plus de code qu'ils ne le feraient en utilisant des rappels. Étant donné qu'il n'y a évidemment aucun avantage à le faire, vous pouvez au moins toujours vous dire que le code est moins couplé ou quelque chose.

Voir quelles sont les promesses et pourquoi devrais-je les utiliser pour les avantages concrets réels.

4
Esailija