angulaire.js - Comment écrire des appels de chaîne de promesses
高洛峰
高洛峰 2017-05-15 16:51:30
0
4
544

Par exemple, j'ai un A.func1() qui est asynchrone et qui peut renvoyer un objet x1. J'ai aussi un B.func2() qui est également asynchrone et doit être exécuté en fonction de x1, puis B. .func2 renvoie une valeur finale t, et certains affichages d'invites seront effectués en fonction de cette valeur finale t. Comment dois-je écrire cela ?
Le code que j'ai écrit moi-même est comme ça

A.func1().
    then(function(x1) {
        B.func2(x1).
            then(function(t) {
                //do something
            })
    })

Mais on a l'impression que l'effet est le même, que vous l'utilisiez ou non... ça se transforme quand même en pyramide

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

répondre à tous(4)
世界只因有你

En réponse au commentaire supplémentaire dans les commentaires sur "sauver l'état lors de l'appel continu de promesses", j'aimerais élaborer sur plusieurs stratégies

La meilleure stratégie : la dé-déclaration

Autrement dit, ajustez votre logique pour que le processus appelant de A.func1, B.func2 et la fonction anonyme (appelons-la func3) ne contienne pas d'état, c'est-à-dire que func3 s'appuie uniquement sur la sortie de func2 , pas la sortie func1 ; ou laissez func2 ne pas dépendre de func1, utilisez quelque chose comme Promise.all pour obtenir les résultats de func1 et func2 en même temps et lancez-les dans func3

Stratégie centrale : statut de maintenance variable "global"

Avantages : l'état peut être étendu à state.x2 .x3...
Problème : Si une longue chaîne d'appels a des états complexes, il est facile de contaminer des bugs, et la maintenabilité du code sera sérieusement réduite

js
function yourLogic() { var state = {}; return A.func1() .then(function(x1) { state.x1 = x1; return B.func2(x1); }) .then(function(t) { //play with t & state.x1 return yourResult; }); }
La méthode bind de

bluebird peut lier thisArg et peut être utilisée pour conserver l'état. Le principe est le même

.
js
function yourLogic() { return A.func1() .bind({})//新建空对象用于保留状态 .then(function(x1) { this.x1 = x1; return B.func2(x1); }) .then(function(t) { //play with t & this.x1 return yourResult; }); }

La stratégie du milieu : livraison supplémentaire temporaire

Avantages : Sans état, si la chaîne d'appel est longue, cet état supplémentaire est contrôlé entre deux étapes, conservant une meilleure maintenabilité et moins sujet aux bugs
Inconvénients : Si chaque étape d'une longue chaîne d'appels a un état, elle deviendra extrêmement verbeuse

js
function yourLogic() { return A.func1() .then(function(x1) { return B.func2(x1) .then(function(t) { return { t: t, x1: x1 } }); }) .then(function(state) { //play with state.t & state.x1 return yourResult; }); }

Bien sûr, l'intérieur peut également être encapsulé et optimisé par vous-même

js
function yourLogic() { return A.func1() .then(function(x1) { return keepState(B.func2(x1), { x1: x1 }, 't'); }) .then(function(state) { //play with state.t & state.x1 return yourResult; }); } function keepState(promise, state, key) { return promise.then(function(value) { state[key] = value; return state; }); }

Dernière solution : Etat de maintenance fermeture

En fait, c'est la manière originale d'écrire la question. Je pense que le principal problème est que la question a été rétrogradée à "l'enfer du rappel" d'origine ou à l'embarras de la pyramide de rappel

L'avantage c'est que...ça marche

js
function yourLogic() { return A.func1() .then(function(x1) { return B.func2(x1) .then(function(t) { //play with t & x1 return yourResult; }); }) }
世界只因有你

Renvoie un objet de then directement à l'intérieur de Promise, comme suit :

javascript
A.func1() .then(function (x1) { return B.func2(x1); }) .then(function (t) { // do something });

En réponse au problème évoqué dans votre commentaire, si vous n'utilisez pas la bibliothèque Promise tierce, vous pouvez l'utiliser comme suit :

javascriptvar promise = new Promise(function (resolve, reject) {
    var firstValue;
    A.func1()
        .then(function (x1) {
            firstValue = x1;    // 临时保存
            return B.func2(x1);
        }, reject)
        .then(function (x2) {
            resolve({
                firstValue: firstValue,
                secondValue: x2
            });
        }, reject);
});

promise.then(function (result) {
    console.log(result);    // {"firstValue": "Hello", "secondValue": "World"}
});

L'utilisation d'une bibliothèque Promise tierce peut simplifier ce processus.

巴扎黑

Promise renverra un objet de promesse, afin qu'il puisse utiliser des appels en chaîne élégants.

过去多啦不再A梦

Si la valeur de retour de la fonction in then est une quantité directe, elle sera utilisée comme paramètre de then du prochain appel de chaîne
Si la valeur de retour a l'interface de promesse, le résultat de la résolution de la promesse est renvoyée
Utilisez q comme exemple

var q = require('q');

var a = function(){
  var d = q.defer();

  d.resolve(1);
  return d.promise;
};

a().then(function(r){
  console.log(r); // 此处是1
  return 2;
}).then(function(r){
  console.log(r);  // 此处2,是由上一个then返回的
  var d = q.defer();
  d.resolve(3);
  return d.promise;
}).then(function(r){
  console.log(r); // 此处是3,由上一个then返回的promise的resolve提供.当需要异步调用时直接return的值肯定不够用,这时就需要返回promise对象.
});
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal