каков правильный способ разрешения обещаний Angularjs внутри $q.all

У меня возникла проблема с разрешением обещаний при использовании $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);
      })

    })

  });

person smart987    schedule 16.01.2015    source источник
comment
Ваш первый цикл бесполезен: вы не должны явно ссылаться на promises внутри функции then(), поскольку у вас уже есть все данные в массиве allData. Не уверен, что я достаточно ясно выразился.   -  person Blackhole    schedule 16.01.2015
comment
Что сказал @Blackhole, а также... нам действительно нужно увидеть весь код, который вы разместили, чтобы вы могли спросить о $q.all?   -  person New Dev    schedule 16.01.2015
comment
Вы хотите, чтобы я сделал что-то вроде angular.forEach(allData , function(data) {...}) внутри функции then()?   -  person smart987    schedule 16.01.2015
comment
Спасибо @Blackhole, я редактирую вопрос.   -  person smart987    schedule 16.01.2015


Ответы (1)


Проблема в том, что $q.all не возвращает сами обещания в разрешенном состоянии, а возвращает их значение напрямую. Таким образом, хотя вы хотите получить промисы внутри вызова $q.all, вы получаете значения. Чтобы обойти это, вы получаете доступ к обещаниям в закрытии.

Попробуйте настроить свой код так, чтобы он работал со значениями вместо обещаний внутри вызова .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;
            .....
        }
    });
});

Так что в целом ваш подход работает (хорошая работа) - но может быть и лучше :)

Также обратите внимание, что событий прогресса, вероятно, следует избегать, и они не являются доказательством будущего.

person Benjamin Gruenbaum    schedule 16.01.2015
comment
Я принимаю ответ, но хотел бы повторить ваш комментарий. В целом ваш подход работает (хорошая работа), но может быть и лучше. Какой лучший вариант вы могли бы предложить мне в этом случае? - person smart987; 16.01.2015
comment
У меня есть еще один вопрос, есть ли возможность избежать задержек при сборе всех промисов в очередь и последующем разрешении. Вскоре обещание доступно, я хотел бы решить там сам. Соответствующий вопрос можно найти по адресу stackoverflow.com/questions/27960174/how-to-minimize-the-delays-in-collecting-all-promises-in-angular-js?noredirect=1#comment44314227_27960174. Есть ли какое-нибудь решение для этого? - person smart987; 16.01.2015
comment
@mnkb подход, который у вас был в вопросе (имеющий тогда в .all), работает, но подход, который не нужно демонстрировать в ответе, в этом не нуждается (таким образом, он лучше). Я посмотрю на ваш другой вопрос. - person Benjamin Gruenbaum; 16.01.2015