我在这里使用AngularJS,但如果你有更通用的答案,我会很高兴知道它。
我有一个包含id的元素数组
myArray = [{
id: 0,
foo: "foo"
}, {
id: 1,
bar: "bar"
}]
使用这些id询问信息的服务,它将参数作为参数(对于请求)和两个回调,一个用于成功,一个用于错误(两个都不是必需的)。
Service.getInformations({id: 1}, onSuccess, onError)
我想做的是这样的事情:
myArray.map(function (element){
Service.getInformations({id: element.id}, function(data) {
return data; // here is the issue
})
});
这里的问题是我在服务回调函数中返回数据而不是在map回调函数中。我正在努力找到一些好办法。
答案 0 :(得分:1)
链接异步函数是一个棘手的老问题。这是在Vanilla Javascript(有或没有Angular)中执行此操作的方法:
var myArray = [
{
id: 0,
foo: "foo"
},
{
id: 1,
bar: "bar"
}
];
var asyncChain = function(myFunction){
var nextThingToDo = function(){
myFunction(nextThingToDo);
}
nextThingToDo();
}
// In this example, myFunction is getArrayItemInfo
// nextThingToDo is goToNextArray Item
// This is how Express.js and Node do things
// Yes, nextThingToDo is calling itself
// If this seems weird, it's because it is. Yay, Javascript.
var index = 0;
var getArrayItemInfo = function(goToNextArrayItem){
if(index < myArray.length){
Service.getInformations({id: index}, function(data){
myArray[index].data = data; // You can do something with the data here
index += 1;
goToNextArrayItem(); // Move on to the next item when the asynchronous part is done
// Without this, execution would stop here
});
}
}
asyncChain(getArrayItemInfo);
这是一个简单的例子,您可以在没有Angular的情况下尝试:
var myArray = ["One sec", "Two secs", "Three secs", "...and that's all."];
var asyncChain = function(myFunction){
var next = function(){
myFunction(next);
}
next();
}
var index = 0;
var getArrayItemInfo = function(goToNextArrayItem){
if(index < myArray.length){
setTimeout(function(){
document.write(myArray[index] + "<br />");
index += 1;
goToNextArrayItem();
}, 1000);
}
}
asyncChain(getArrayItemInfo);
答案 1 :(得分:1)
你可以做这样的事情,在角上使用内置的$ q服务。
您可以迭代元素,调用服务并返回promise并仅在所有异步操作完成时执行回调。
在这种情况下,回调会从各自的调用中获取一系列结果。
var app = angular.module("sampleApp", []);
app.controller("sampleController", ["$scope", "$q", "sampleService",
function($scope, $q, sampleService) {
var randomArray = [1, 2, 3, 4, 5, 6];
var promisesArray = randomArray.map((input) => {
return sampleService.getInformations(input)
});
$q.all(promisesArray).then(function(outputArray) {
console.log("Results Array");
console.log(outputArray);
});
}
]);
app.service("sampleService", function() {
this.getInformations = function(value) {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
value = value * 2;
resolve(value);
}, 1000);
});
return promise;
};
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="sampleApp">
<div ng-controller="sampleController">
</div>
</div>
&#13;
答案 2 :(得分:0)
Promise.all(myArray.map(item => new Promise((resolve, reject) => {
Service.getInformations({id: item.id}, resolve, reject)
}).then((resultArray) => {
//reduce result
}).catch((errorArray)=> {
//reduce error
})