2016-02-06 3 views
0

Предположим, у нас есть 3 обещания, и мы передаем их в $ q.all. Это вернет новое обещание, которое будет разрешено, когда будут разрешены 3 обещания.

Теперь, если до 3 обещаний разрешено, я на самом деле решаю, что я хочу, чтобы 4-е обещание было разрешено, может ли это быть сделано?

Я пытался что-то вроде:

var promises = [promise1, promise2, promise3]; 
var allDone = $q.all(promises); 
promises.push(promise4); 

В вышеприведенном allDone решена, как только первые 3 обещания будут решены, но я хотел бы, чтобы ждать 4-го обещания, а также.

Или я пропущу точку обещаний здесь? Может быть, я не должен использовать обещания для таких случаев?

Обновление: Как ответ, $ q.all не способен делать то, что я хочу. Мой вопрос: есть ли другой способ узнать, когда динамический набор обещаний будет разрешен, так что даже если этот набор изменится?

ответ

1

Вы не можете добавить обещания в массив после факта и ожидать, что это повлияет на предыдущие .all(). Это не так, как работает .all(). Вы можете, вместо этого:

var promises = [promise1, promise2, promise3]; 
var allDone = $q.all(promises); 

$q.all([allDone, promise4]).then(function() { 
    // all four promises are done here 
}); 

Или, вы можете просто abandone в allDone обещание и переделать новый .all() так:

var promises = [promise1, promise2, promise3]; 
var allDone = $q.all(promises); 

promises.push(promise4); 
var all4Done = $q.all(promises); 

на основе ваших комментариев, вот еще одна возможность. Скажем, конечный обработчик, который вы хотите вызвать, находится в функции с именем allDoneNow(). Тогда вы могли бы сделать что-то вроде этого:

var promises = [promise1, promise2, promise3]; 
var allDone = $q.all(promises); 
allDone.then(function(results) { 
    // if no new promises have been added to the array 
    if (promises.length === results.length) { 
     // call our final handler 
     return allDoneNow(results); 
    } else { 
     // wait for any new promises 
     return $q.all(promises).then(allDoneNow); 
    } 
}); 

promises.push(promise4); 

Или, если вы хотите его рекурсивный так он продолжает проверять больше, вы можете поместить его в функцию, как это, что можно использовать рекурсивно:

function waitAll(promiseArray) { 
    return $q.all(promiseArray).then(function(results) { 
     if (promiseArray.length <= results.length) { 
      // everything currently in the promiseArray is now done 
      return results; 
     } else { 
      // there are some new things in the promiseArray so 
      // wait until they are done 
      return waitAll(promiseArray); 
     } 
    }); 
} 


var promises = [promise1, promise2, promise3]; 
waitAll(promises).then(function(results) { 
    // all promises currently in the promises array are done 
}); 

promises.push(promise4); 
+0

Хм, но это потребовало бы, чтобы я каким-то образом отменил любой .then() обратный вызов, прикрепленный к первому $ q.all. Я надеялся на более простое решение :-). – user125661

+1

@ user125661 - Вы зарегистрировали обработчик для выполнения трех обещаний. Вы не можете это изменить. Вы можете добавить новых обработчиков, которые будут уведомлять вас о вновь созданных условиях. Если, когда у вас есть первые три обещания, вы знаете, что у вас может быть больше обещаний до того, как будут выполнены первые три, а затем не зарегистрируйте окончательный обработчик. Зарегистрируйте обработчик макета, чья работа заключается в том, чтобы проверить, есть ли еще какие-либо обещания, которые вам также нужно ждать, а если нет, то он может вызвать обработчик. – jfriend00

+0

это имеет смысл! Другое решение, которое я решил, может заключаться в том, чтобы добавить фиктивное обещание к набору из четырех обещаний.Как только я узнаю, что первоначальный набор обещаний должен быть изменен, я могу отказаться от этого обещания и установить новый $ q.all, как вы сказали выше. – user125661

1

Если вы можете проверить исходный код функции $q all(), вы увидите, что он просто отправляет все обещания с помощью forEach() и возвращает другое обещание, которое позже разрешит весь результат.

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

+0

Спасибо! Я предполагаю, что мой реальный вопрос: есть ли способ, которым я мог бы получить такое поведение? – user125661

Смежные вопросы