我正在尝试通过forEach在各种服务的响应中创建一个对象..而且我没有得到我需要的结果。 我知道我应该使用内部迭代承诺,但不知道怎么做..
修改
好吧..我需要做的就是将数据的对象填入$ foreach foreach .. http转换为迭代承诺,示例代码:someservice1.getitem().then(function(){
var dataInfo= {};
angular.foreach(data, function(v, k){
dataInfo[v]=[]
someservice2.getitem2(k.data).then(function(data){
datainfo[v].push(data)
})
})
$scope.dataInfo = datainfo;
})
所以不能很好地工作..我认为你可以通过使用promises解决但我无法做到。 我希望你的帮助
答案 0 :(得分:2)
问题是,在$scope.dataInfo = datainfo;
对象完成之前,最终datainfo
早期执行。您需要创建一个承诺,该操作可以安全地链接。
finalPromise.then ( function (datainfo) {
$scope.dataInfo = datainfo;
});
您可以通过以前的承诺返回和链接来创建finalPromise
。
var service1Promise =
someservice1.getitem().then(function(data){
var promiseList = [];
angular.foreach(data, function(v,k){
var p = someservice2.getitem2(k.data);
p.then(function(data) {
//return key and data for chaining
return { key: k, data: data };
}) .catch (function (error) {
//throw key and error to chain rejection
throw { key: k, error: error };
});
//push to list
promiseList.push(p);
});
//return $q.all promise for chaining
return $q.all(promiseList);
});
从finalPromise
service1Promise
var finalPromise =
service1Promise.then(function(fulfilledList) {
var dataInfoObj = {};
//assemble data info
angular.forEach(fulfilledList, function (fulfilledItem) {
dataInfoObj[fulfilledItem.key] = fulfilledItem.data;
});
//return datainfoObj for chaining
return datainfoObj;
});
现在,您可以从finalPromise
链将数据放在$scope
finalPromise.then ( function onFulfulled (datainfo) {
$scope.dataInfo = datainfo;
}).catch (function onRejection (error) {
console.log("finalPromise rejected");
console.log(error.key);
console.log(error.error);
});
请注意$q.all
不具弹性。如果任何承诺被拒绝,$q.all
将在第一次拒绝后被拒绝。
有关链接承诺的更多信息,请参阅AngularJS $q Service API Reference -- chaining promises。
答案 1 :(得分:1)
你正在使用angularjs,所以使用$q
,对于promises中的promises数组,你可以使你的代码成为这样的代码:
// first add $q service to your controller,
someservice1.getitem()
.then(function(data){
var dataInfo= {};
var promises = angular.map(data, function(item, index){
var promises2 = angular.map(item.data, function(iData){
someservice2.getitem2(iData)
})
return $q.all(promises2).then(function(resultArray){
dataInfo[index] = resultArray;
});
});
return $q.all(promises).then(function(){
console.log('all data are retrived...');
$scope.dataInfo = datainfo;
});
});
在ES6中看起来更优雅:
let serviceCall2 = data => someservice2.getitem2(data); // serviceCall2 is just a closure for someservice2.getitem2() call
someservice1.getitem()
.then(data => {
let dataInfo= {},
promises = data.map((item, index) => {
let promises2 = item.data.map(serviceCall2);
return $q.all(promises2).then(resultArray => dataInfo[index] = resultArray);
});
return $q.all(promises)
.then(() => {
console.log('all data are retrived...');
$scope.dataInfo = datainfo;
});
});