如何使用.map()为数组元素分配promise的结果?

时间:2016-11-03 05:34:14

标签: javascript angularjs arrays promise array.prototype.map

我在这里使用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回调函数中。我正在努力找到一些好办法。

3 个答案:

答案 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并仅在所有异步操作完成时执行回调。

在这种情况下,回调会从各自的调用中获取一系列结果。

&#13;
&#13;
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;
&#13;
&#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
})