Javascript 如何使用reduce和promissions等待数组中每个元素的异步请求
我不熟悉AngularJS和JavaScript 我正在获取阵列(cars)中每个元素的远程信息,并创建一个新阵列(感兴趣的潜在客户)。所以我需要同步这些请求。我需要将每个请求的响应以与汽车相同的顺序添加到新数组中 我首先做的是一个:Javascript 如何使用reduce和promissions等待数组中每个元素的异步请求,javascript,jquery,angularjs,angular-promise,Javascript,Jquery,Angularjs,Angular Promise,我不熟悉AngularJS和JavaScript 我正在获取阵列(cars)中每个元素的远程信息,并创建一个新阵列(感兴趣的潜在客户)。所以我需要同步这些请求。我需要将每个请求的响应以与汽车相同的顺序添加到新数组中 我首先做的是一个: for (a in cars) { //async request .then(function () { //update the new array }); } 这会发出所有请求,但自然不会更新新阵列 在论坛中搜索之后
for (a in cars) {
//async request
.then(function () {
//update the new array
});
}
这会发出所有请求,但自然不会更新新阵列
在论坛中搜索之后,我找到了这些关于返回中间承诺的好例子和解释,并同步了所有这些例子和解释
1. http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
2. http://stackoverflow.com/questions/25605215/return-a-promise-from-inside-a-for-loop
3. http://www.html5rocks.com/en/tutorials/es6/promises/
(@Maurizionindenmark、@Mark Rajcok、@Michelle Tilley、@Nolan Lawson)
我无法使用第二次引用中建议的Promise.resolve()。所以我使用了$q.defer()
和resolve()
。我想我必须注入一个依赖项或其他我错过的东西。如下图所示:
在控制器中,我有:
$scope.interestedProspects = [] ;
RequestDetailsOfAsync = function ($scope) {
var deferred = $q.defer();
var id = carLists.map(function (car) {
return car.id;
}).reduce(function (previousValue, currentValue) {
return previousValue.then(function () {
TheService.AsyncRequest(currentValue).then(function (rData) {
$scope.interestedProspects.push(rData);
});
});
}, deferred.resolve());
};
在这项服务中,我有如下几点:
angular.module('app', []).factory('TheService', function ($http) {
return {
AsyncRequest = function (keyID) {
var deferred = $q.defer();
var promise = authorized.get("somep.provider.api/theService.json?" + keyID).done(function (data) {
deferred.resolve(data);
}).fail(function (err) {
deferred.reject(err);
});
return deferred.promise;
}
}
}
我得到的显示错误:未捕获类型错误:previousValue.then不是函数
我使一个JSFIDLE可以重用其他JSFIDLE,这样可以更容易地解决这个问题。如何使用reduce和promissions等待数组中每个元素的异步请求
我不知道错误是否是:
- 在控制器函数中放置解析的位置
- reduce函数的使用方式
previousValue和currentValue有时被类似javascript的承诺类型最初视为一个数字。在JSFIDLE中,我有一个使用reduce的工作示例和一个http请求作为示例。似乎您正在对一个ID数组调用reduce
,但在传递的函数中假设您正在处理承诺
通常,当您想要同步一组承诺时,可以使用
您传递了一系列承诺,并得到另一个承诺作为回报,该承诺将通过一系列结果得到解决。看看这个模式,了解您想要做什么:
cars.reduce(function(promise, car) {
return promise.then(function(){
return TheService.AsyncRequest(car).then(function (rData) {
$scope.details.push(rData);
});
});
}, $q.when());
这将按照cars数组中的顺序对每个car执行所有异步调用$q。如果异步调用的顺序无关紧要,那么所有的
可能也就足够了。你的提琴与问题无关。你的提琴与减少承诺没有任何关系,那么它与承诺有什么关系呢?我不能使用Promise.resolve()
-所以使用$q.resolve()
而不是延迟反模式Service.AsyncRequest(currentValue)
是否返回承诺?您的服务不是有效的javascriptreturn{AsyncRequest=function(){}
可能是return{AsyncRequest:function(){}
-它必须返回与控制器代码兼容的承诺谢谢,这解决了我的问题。是的,顺序很重要,并且不需要使用array.reduce,这是因为我尝试的方法都不起作用(第一次使用承诺)。顺便问一下,您的意思是$q.all将是您发布的模式中不按顺序分配响应的q.when()的替代品吗?不,$q.all是处理多个返回承诺的异步调用的不同方式。很高兴我能帮忙。请接受此答案,以帮助其他可能有相同问题的人。如果我想获得同步异步请求的Promise实例,请取消对代码的测试。我该怎么办?顺便问一下,有没有一种方法可以简化具有相同需求的代码?如果是这样,怎么做?另外,我需要再次帮助,我尝试访问其中的信息,然后它记录了一个错误承诺无法读取未定义的属性“replace”。因为我想替换一些字符。因为这是关于原始问题的离题,你也许应该问一个新的。