Последовательные обещания

#javascript #angularjs #angular-promise

#javascript #angularjs #angular-обещание

Вопрос:

Мне нужно получить четыре обещания ответа, но для этого мне сначала нужно вызвать каждую функцию последовательно, от первой до последней. Вы можете видеть из моего кода, что я вызываю следующую функцию в обратном вызове обещания из последней вызванной функции.

Но код выглядит неподходящим, поэтому мне нужно знать, есть ли какой-то лучший способ сделать это.

Есть предложения?

 $scope.createPayment = function() {
    var dados = $scope.card;
// get first promise
    PagamentoMP.createToken(dados)
    .then(
        function(result) {
            dados.token = resu<
// get second promise
            PagamentoMP.guessPaymentMethod(dados)
            .then(
                function(result) {
                    dados.paymentMethod = resu<
// get third promise            
                    PagamentoMP.getIssuers(dados)
                    .then(
                        function(result) {
                            dados.issuer = resu<
// get fourth promise 
                            PagamentoMP.getInstallments(dados)
                            .then(
                                function(result) {
                                    dados.installments = resu<     
                                },  
// error for fourth promise
                                function(result) {
                                    console.log("getInstallments PAGAMENTOMP -> Failed to get the name, result is "   result); 
                                }
                            );
                        },
// error for third promise                      
                        function(result) {
                            console.log("getIssuers PAGAMENTOMP -> Failed to get the name, result is "   result); 
                        });
                    },
// error for second promise                 
                    function(result) {
                        console.log("guessPaymentMethod PAGAMENTOMP -> Failed to get the name, result is "   result); 
                    });
                },
// error for first promise              
            function(result) {
                console.log("createToken PAGAMENTOMP -> Failed to get the name, result is "   result); 
            });
    };
  

Комментарии:

1. Я не знаю, имеете ли вы какой-либо контроль над функциями, которые возвращают обещания. Если вы это сделаете, я бы подумал о том, чтобы переработать их, чтобы вы могли избежать такого количества асинхронных вещей. Я всегда рассматриваю красный флаг, если мне приходится вставлять обещания более одного раза.

Ответ №1:

Вместо того, чтобы делать это,

 a().then(function(result) {
    b(result).then(function(result) {
        c(result).then(function(result) {
            console.log("done");
        });
    });
});
  

вы можете связать все обещания на верхнем уровне.

 a()
    .then(function(result) {
        return b(result);
    })
    .then(function(result) {
        return c(result);
    })
    .then(function(result) {
        console.log("done");
    });
  

Этот же шаблон можно использовать в вашем коде.

Чтобы перехватывать ошибки, добавьте a .catch в конце цепочки, если вам нужен один обработчик ошибок для всех ошибок в цепочке.

 a()
    .then(function(result) {
        console.log("done");
    })
    .catch(function(err) {
        console.error(err);
    });
  

Для отдельных обработчиков ошибок на каждом шаге вы можете сделать что-то вроде этого:

 a()
    .catch(function(err) {
        console.log("error in a");
        throw err;
    })
    .then(function(result) {
        return b()
            .catch(function(err) {
                console.log("error at b");
                throw err;
            });
    })
    .then(function(result) {
        return c()
            .catch(function(err) {
                console.log("error at c");
                throw;
            });
    });
  

Каждый обработчик ошибок должен вызываться throw , чтобы он не продолжался по цепочке, когда возникает ошибка.

Комментарии:

1. Большое вам спасибо @afuous Как насчет ответа на ошибку? Как мне получить и обработать это?

2. Хорошо, но если я хочу получать отдельное сообщение об ошибке для каждого ответа?

3. @vinoli Да, первое обещание в цепочке немного неудобно, поскольку оно находится на верхнем уровне, а не внутри одного из обратных then вызовов . Обратите внимание, что a().catch(...) вверху то же самое, что b().catch(...) и c().catch(...) внутри одного из обратных вызовов. Если вы хотите, вы можете начать цепочку с Promise.resolve().then(...) и поместить a() внутрь первого обратного вызова, чтобы он выглядел так же, как b() и и c() , но он будет работать так, как сейчас.