我从Web服务获取数据,我需要将此数据发送到另一个服务以修改某些值,因此当我获取数据时,会有更多的异步调用。我不知道如何获得最终价值。
我想叫什么:
SomeService.getSomething(id).then(function(something) {
SomeOtherService.addXToDatas(something.data).then(function(fixedData) {
$scope.data = fixedData;
});
});
我有什么:
someOtherService.addXToDatas = function(datas) {
datas.forEach(function(value, index, array) {
getSomethingFromApi(value.something).then(function(bla) {
array[index] = bla;
});
});
}
someOtherService.addXToData = function(data) {
getSomethingFromApi(data.something).success(function(response) {
order.someMore = response.data;
});
}
}
不幸的是,我没有真正的线索如何在javascript中完成此任务。 对于单个对象,我可以使用回调,但是对于一个对象列表?
答案 0 :(得分:1)
如果我理解正确你想要一个数组填充来自addXToDatas
中的异步调用的数据,你可以这样做:
someOtherService.addXToDatas = function(datas) {
var promises = [];
datas.forEach(function(value, index, array) {
promises.push(
getSomethingFromApi(value.something)
);
});
return $q.all(promises);
}
在你的控制器中:
someOtherService.addXToDatas([data1, data2,data3])
.then(function(resultArray) {
console.log(resultArray);
});
$q.all(promises)
将返回一个数组(按顺序)和promises的值。有关$q
和$q.all
here的更多信息。
答案 1 :(得分:1)
Angular.js具有Q的内置实现,因此您可以使用promise组合Q.all
。它需要一系列承诺,并返回在所有其他承诺都履行时履行的承诺。
您可以使用.map
代替.forEach
轻松地使用您的代码创建承诺数组:
someOtherService.addXToDatas = function(datas) {
return $q.all( datas.map(function(value, index, array) {
return getSomethingFromApi(value.something).then(function(bla) {
array[index] = bla;
});
})).then(function() {
return datas;
});
}
SomeOtherService.addXToDatas(something.data).then(function(fixedData) {
$scope.data = fixedData;
});
datas.map()
创建一系列承诺。 API调用本身将异步执行。$q.all()
返回一个承诺,当履行了从(1)传递给它的所有承诺时,承诺就会履行。then
会返回修改后的data
数组。在完成(1)的所有承诺并完成data
的所有修改之后调用它。