Я создаю объекты с использованием внешнего источника с намерением обработать их стиль обратного вызова. К сожалению, эти обратные вызовы могут переместиться за пределы стека браузера, и я должен помнить о наихудшем сценарии 500 для IE.
Я переписал свой код с помощью $ q.when
$scope.combinations.forEach(function(combination) {
chain = chain.then(function() {
return generateConfiguration(combination);
});
});
generateConfiguration, если функция возвращает обещание. Все работает отлично, но я хочу добавить finally() в конце цепочки.
То, что я сделал до сих пор, - это иметь трекер внутри generateConfiguration, который распознает последнюю комбинацию и запускает то, что должно было быть вызвано, наконец.
Есть ли более чистый способ сделать это?
Это зависит от того, что вы хотите сделать.
Вы создаете обещание цепи, так что если вы хотите сингл, finally
, для цепи, просто добавьте его в конце после того, как строить его с этим forEach
:
// ...your forEach here, then:
chain.finally(/*...*/);
Если вы хотите, finally
выполнить каждое обещание от generateConfiguration
, либо предоставите себе функцию-оболочку, либо сделайте это внутри обратного вызова forEach
.
$scope.combinations.forEach(function(combination) {
chain = chain.then(function() {
return generateConfiguration(combination).finally(/*...*/); // <==
});
});
Сторона примечания: Там более идиоматический способ построить эту цепочку, посредством reduce
:
var chain = $scope.combinations.reduce(function(chain, combination) {
return chain.then(function() {
return generateConfiguration(combination);
});
}, Promise.resolve());
Добавление окончательного finally
варианта (вариант № 1 выше):
var chain = $scope.combinations.reduce(function(chain, combination) {
return chain.then(function() {
return generateConfiguration(combination);
});
}, Promise.resolve())
.finally(function() {
// ...do stuff here...
});
Да, есть: ввести $q
(т.е. рамки обещаний) и переписать
$q.all($scope.combinations.map(function(combination) {
return generateConfiguration(combination);
})).finally(function(res) {
/* ... */
});
Таким образом, вы также будете отключать все generateConfiguration (s) параллельно (по крайней мере, как можно больше - например, ограничение на, например, XHR). В любом случае: $q.all(arrayOfPromises)
может быть тем, что вы искали.
$q.all
обрабатывает их параллельно (как стандартный Promise.all
, который, я считаю, был вдохновлен q)?
chain.finally(…)
после цикла?