связанное обещание в цикле for не выполняется должным образом

#angularjs #angular-promise

#angularjs #angular-обещание

Вопрос:

У меня есть цепные обещания, которые отлично работают в одной серии, но теперь я хочу вызвать эту цепочку внутри цикла for, но она работает не так, как ожидалось.

посмотрите мой демонстрационный плунжер и посмотрите вывод в консоли.

ниже приведена структура моих связанных обещаний . Мне нужны все PublicIP, возвращаемые funTwo ; но я хочу завершить funThree() , а затем хочу получить все PublicIP. Насколько я знаю, это $q.when() создает значение в объекте promise.

но вы можете видеть, что оно console.log('pA', promiseArray); выполнялось задолго до и console.log('res three'); и почему successHandler и finally вызывалось до этого?

Здесь, конечно, я чего-то не хватает, возможно, придется написать return; в нужном месте, пожалуйста, помогите мне, как выполнить все функции в цикле for и вернуть массив данных после завершения цикла for, который можно повторить в successHandler

  MyService.funZero()
     .then(function(response) {
        console.log(response);
        var promiseArray = [];
        for(var i = 0; i < 2 ; i  ) {
            console.log('I', i);
            MyService.funOne()
           .then(MyService.funTwo)
           .then(function(res2) {
                console.log('res two', res2);
                publicIP = res2.ip;
                console.log('i', publicIP);
                promiseArray.push({'ip': publicIP});
                return MyService.funThree(publicIP);
           })
           .then(function() {
                 console.log('res three');
           })
           } // for loop ends
        console.log('pA', promiseArray);
        return $q.when(promiseArray);
      })
      .then(function(res4){
          console.log('after for loop', res4);
      })
      .then(successHandler)
      .catch(errorHandler)
      .finally(final, notify);
  

Комментарии:

1. это не дубликат @Phil .. Я уже читал это, но не понял, как применить в AngularJS.

2. Вы правы, мои извинения.

3. разве PromiseArray не является просто массивом объектов? но название подразумевает иное, и вы выполняете $ q.when(PromiseArray)

4. да, promiseArray это массив, я хочу превратить его в объект promise, используя ` $ q.когда`, чтобы он мог быть доступен в next .then() ? разве это не правильный способ?

Ответ №1:

Итак, я не уверен точно, что делает MyService.funThree, но вы можете объединить массив с помощью ipArray.push({'ip': publicIP}) и вернуть его в MyService.funThree , а затем в последующую функцию. Проблема здесь в том, что нет гарантии порядка в ipArray , если это то, что вы ищете. Вот средняя часть этой функции:

 ipArray = [];
for(var i = 0; i < 2 ; i  ) {
  console.log('I', i);
  var promise = MyService.funOne()
    .then(MyService.funTwo)
    .then(function(res2) {
      console.log('res two', res2);
      publicIP = res2.ip;
      console.log('i', publicIP);
      ipArray.push({'ip': publicIP});
      return ipArray;
    })
    .then(MyService.funThree)
    .then(function() {
      console.log('res three');
    });

  promiseArray.push(promise);
}
console.log('pA', promiseArray);
return $q.all(promiseArray);
  

Комментарии:

1. Спасибо за ценный вклад, но в моей ситуации MyService.funThree() использовались данные из `res2`; поэтому невозможно исключить funThree в next ` .then()`

2. Тогда вместо того, чтобы возвращаться ipArray сюда, вы можете вернуться res2 и передать его в качестве аргумента в MyService.funThree .