如何使用reduce和promises等待阵列中每个元素的AsyncRequests

时间:2015-12-06 08:21:54

标签: javascript jquery angularjs angular-promise

我是AngularJS和JavaScript的新手。

我正在获取数组(汽车)的每个元素的远程信息并创建一个新数组(感兴趣的潜在客户)。所以我需要同步请求。我需要将每个请求的响应按照汽车的相同顺序添加到新阵列中。

我先用for:

做了
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/

(@ MaurizioIndenmark,@ 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;
        }
    }
}

我收到的显示错误:Uncaught TypeError: previousValue.then is not a function

我重复使用其他可用的jsfiddle,以便更容易解决这个http://jsfiddle.net/alisatest/pf31g36y/3/。如何使用reduce和promises

等待阵列中每个元素的AsyncRequests

我不知道错误是否是:

  • 解析在控制器功能中的位置。
  • 使用reduce函数的方式

以前的值和PromV​​alue有时会被类似Promise的类似javascript看作一个数字。在jsfiddle中,我有一个使用reduce的示例和示例的http请求。

2 个答案:

答案 0 :(得分:0)

似乎你在一个id数组上调用reduce,但在传递的函数中假设你正在处理promises。

通常,当您要同步一组承诺时,可以使用$q.all

你传递了一系列的promises并获得了另一个可以通过一系列结果解决的承诺。

答案 1 :(得分:0)

看看这个模式你想做什么:

        cars.reduce(function(promise, car) {
            return promise.then(function(){
              return TheService.AsyncRequest(car).then(function (rData) {
                $scope.details.push(rData);
              });
            });
        }, $q.when());

这将完全按照它们在汽车阵列中的顺序对每辆汽车进行所有异步调用。如果异步调用的顺序无关紧要,$q.all也可能就足够了。