#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()
, но он будет работать так, как сейчас.