如何使用reduce和promise为数组中的每个元素等待AsyncRequest

How to wait for AsyncRequests for each element from an array using reduce and promises

本文关键字:元素 AsyncRequest 等待 数组 reduce 何使用 promise      更新时间:2023-09-26

我是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和promise 为数组中的每个元素等待AsyncRequest

我不知道错误是不是:

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

previousValue和currentValue有时会被类似javascript的Promise类型最初看作数字。在jsfiddle中,我有一个使用reduce的工作示例和一个http请求。

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

        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.all也可能足够了。

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

一般来说,当你想同步一组承诺时,你可以使用$q.all

您传递一个promise数组,然后得到另一个promises作为回报,该promise将通过一个结果数组来解决。