【问题标题】:what is the right way of resolving the Angularjs promises inside $q.all解决 $q.all 中的 Angularjs 承诺的正确方法是什么
【发布时间】:2015-03-14 17:40:04
【问题描述】:

我在解决使用 $q.all 的承诺时遇到了问题,有人可以帮帮我吗?

当我有一个单一的承诺时,以下工作正常:

 var dashlettePromise = DashboardsDataService.getTabDetails(dashboardData);
    dashlettePromise.then(function(data) {
      var template = '<div class= "allChartsDiv">';

      for (var dashVar = 0; dashVar < data.tabDetails.length; dashVar++) {
        var dashletteId = data.tabDetails[dashVar].dashletteId; // Added
         ....
      }
    }, function(error) {
      alert(error);
    }, function(progress) {
      // report progress
    });

但我需要进行多次 ajax 调用,所以我使用了 $q.all,如下所示:

var promises = [];
angular.forEach(dashboardslayoutArray, function(dashboardslayout) {
  dashboardData.dashletteBeansList = [];
  dashboardData.dashletteBeansList[0] = dashboardslayout;
  var dashlettePromise = DashboardsDataService.getTabDetails(dashboardData);
  promises.push(dashlettePromise);

});

现在我需要一一解决 $q.all 中的所有承诺,与我为单个承诺解决的承诺完全相同,如上所示。所以我使用了下面显示的代码,但它没有按预期工作。我开始怀疑我在 $q.all(promises) 中使用的逻辑来解决这些承诺。这是正确的方法吗?或者任何人都可以提出更好的方法来解决 $q.all 中的承诺?

$q.all(promises)
  .then(function(allData) {
    // all promises were resolved here                          
    angular.forEach(promises, function(eachPromise) {

      eachPromise.then(function(data) {

        for (var dashVar = 0; dashVar < data.tabDetails.length; dashVar++) {
          var dashletteId = data.tabDetails[dashVar].dashletteId; // Added
          var axisType = data.tabDetails[dashVar].axisType;
            .....
        }

      }, function(error) {
        alert(error);
      })

    })

  });

【问题讨论】:

  • 您的第一个循环是无用的:您不应该在then() 函数中明确引用promises,因为您已经拥有allData 数组中的所有数据。不知道我是否足够清楚。
  • @Blackhole 说了什么,还有......我们真的需要查看您发布的所有代码,以便您询问$q.all吗?
  • 你想让我在 then() 函数中做类似 angular.forEach(allData , function(data) {...}) 的事情吗?
  • 谢谢@Blackhole,我正在编辑问题。

标签: angularjs promise angular-promise angular-services


【解决方案1】:

问题在于$q.all 不会在已解决状态下返回 Promise 本身,而是直接返回它们的值。因此,尽管您希望在 $q.all 调用中获得承诺,但您正在获得价值。为了规避这种情况,您可以在关闭时访问 Promise。

尝试调整代码以处理 .all 调用中的值而不是承诺:

$q.all(promises)
  .then(function(allData) {
    // all promises were resolved here                          
    allData.forEach(function(data) {
    // no `then` needed here
        for (var dashVar = 0; dashVar < data.tabDetails.length; dashVar++) {
          var dashletteId = data.tabDetails[dashVar].dashletteId; // Added
          var axisType = data.tabDetails[dashVar].axisType;
            .....
        }
    });
});

所以总的来说你的方法是有效的(干得好)-但可以更好:)

另请注意,可能应该避免进度事件,并且不是未来的证据。

【讨论】:

  • 我接受答案,但想回应您的评论,“所以总的来说,您的方法有效(做得好) - 但可以更好”。在这种情况下,您会向我建议什么更好的选择?
  • 我还有一个问题,是否有可能避免延迟收集队列中的所有承诺然后解决。承诺尽快可用,我想自行解决。相关问题可以在 stackoverflow.com/questions/27960174/how-to-minimize-the-delays-in-collecting-all-promises-in-angular-js?noredirect=1#comment44314227_27960174 找到。有什么解决办法吗?
  • @mnkb 您在问题中采用的方法(然后在 .all 中)有效 - 但不需要在答案中演示的方法不需要(因此更好)。我会看看你的另一个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-02
  • 2017-10-09
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多