【问题标题】:How to assign the result of a promise to array elements using .map()?如何使用 .map() 将承诺的结果分配给数组元素?
【发布时间】:2017-03-16 14:57:56
【问题描述】:

我在这里使用 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
  })
});

这里的问题是我在服务回调函数中返回数据,而不是在地图回调函数中。我正在努力寻找一些好的方法来做到这一点。

【问题讨论】:

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


    【解决方案1】:

    你可以做这样的事情,在 angular 上使用内置的 $q 服务。

    您可以迭代元素,调用服务并返回一个承诺,并仅在所有异步操作完成时执行回调。

    在这种情况下,回调从它们各自的调用中获取一组结果。

    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;
      };
    });
    <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>

    【讨论】:

      【解决方案2】:

      链接异步函数是一个棘手的老问题。这是在 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);

      【讨论】:

        【解决方案3】:
        Promise.all(myArray.map(item => new Promise((resolve, reject) => {
          Service.getInformations({id: item.id}, resolve, reject)
        }).then((resultArray) => {
          //reduce result
        }).catch((errorArray)=> {
          //reduce error
        })
        

        【讨论】:

        • 如果没有解释,这个答案真的没用。
        • 好的,我不知道promise class,谢谢。对于我的回答,这似乎更准确。然而,下面的答案更有趣(RobertAKARobin & Sreekanth)
        猜你喜欢
        • 2020-05-10
        • 2018-08-30
        • 2019-09-18
        • 2016-11-12
        • 2017-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多