[英]Chaining promises from a foreach loop
var articles = arg;
articles.forEach(function(data){
var promises = [fetchImg(data), fetchUser(data)];
$q.all(promises).then(function (res) {
finalData.push(res[1]);
});
});
return finalData;
我想只在forEach
循环结束后才返回finalData
数组。 有没有办法用承诺链接它? 首先执行foreach循环然后在循环结束后返回数组的东西?
您可以像这样修改代码:
function fetArticles(arg) {
var articles = arg;
var promises = [], finalData = [];
var deferred = $q.defer();
articles.forEach(function(data) {
var userPromise = fetchUser(data);
userPromise.then(function (res) {
finalData.push(res[1]);
});
promises.push(fetchImg(data));
promises.push(userPrommise);
});
$q.all(promises).then(function() {
deferred.resolve({finalData: finalData, foo: "bar"});
});
return deferred.promise;
}
现在,调用此方法并注册最终回调:
fetArticles(arg).then(function(data) {
console.log("finalData: ", data.finalData, data.foo === "bar");
});
通过在.then
方法中向处理函数返回值(或promise)来链接 .then
。 通过使用$q.all
来合并多个$q.all
,它本身返回一个可链接的 promise。
function fetchUsers(arg) {
var articles = arg;
var promises = articles.map(function(a){
var subPromises = [fetchImg(a), fetchUser(a)];
return $q.all(subPromises).then(function (res) {
//return for chaining
return {img: res[0], user: res[1]};
});
});
//consolidate promises
var finalPromise = $q.all(promises);
return finalPromise;
};
因为调用promise的.then
方法会返回一个新的派生promise,所以很容易创建一个promise链。 可以创建任何长度的链,并且由于可以使用另一个承诺(将进一步推迟其解析)来解决承诺,因此可以在链中的任何点暂停/推迟承诺的解析。 1
返回的promise将通过一组用户解析完成,或者在第一个错误时解析被拒绝。 最终解决与承诺的检索.then
和.catch
方法。
fetchUsers(args)
.then ( function onFulfilled(objArray) {
$scope.users = objArray.map(x => x.user);
return objArray;
}).catch ( function onRejected(response) {
console.log("ERROR: ", response);
throw response
})
;
$q.defer
反模式 使用$q.defer()
的问题在于它会破坏promise链,丢失错误信息,并且在错误处理不当时可能会造成内存泄漏。 有关详细信息,请参阅AngularJS这是一个“延迟反模式”吗? 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.