Цепочная цепочка при использовании $timeout
Я пытаюсь понять API обещаний и цепочку, особенно время, когда $timeout
используется с .then()
. То, что я ожидал от следующего, состоит в том, что, поскольку $timeout
возвращает обещание, .then()
не будет вызываться до тех пор, пока он не будет разрешен.
Но вместо ABAB это ABBA все время.
Как я могу использовать API обещаний, чтобы гарантировать, что длительный вызов (или задержанный вызов с использованием $timeout
) действительно завершен до того, как будет выполнен .then()
?
код
angular
.module('app', [])
.controller('ThenCtrl', ThenCtrl);
function ThenCtrl($timeout, $q) {
var vm = this;
vm.items = [];
$q.when(pushA()).then(pushB());
$timeout(pushA, 5000).then(pushB());
function pushA() {
vm.items.push('A');
}
function pushB() {
vm.items.push('B');
}
}
Разметка
<div ng-app="app">
<div ng-controller="ThenCtrl as vm">
{{vm.items}}
</div>
</div>
Я создал скрипку: https://jsfiddle.net/kan3c61t/
Ответы
Ответ 1
Не вызывайте функции внутри методов .then
.
$q.when(pushA()).then(pushB);
//$q.when(pushA()).then(pushB());
$timeout(pushA, 5000).then(pushB);
//$timeout(pushA, 5000).then(pushB());
Вместо этого передайте функции как аргументы методу .then
. Служба $q
будет содержать эти функции, которые будут вызываться позже.
Как работает служба $q
, он сохраняет аргумент метода .then
как функцию, которая будет вызвана позже. В этом случае служба $q
сохраняла значение, возвращаемое pushB()
, с побочным эффектом нажатия B
сразу на массив.
DEMO на JSFiddle
Ответ 2
Здесь вы идете.
То, что я сделал, по существу добавило функцию success
в части then
кода.
$timeout(pushA, 5000).then(function(success) {
pushB()
});
Вот рабочая демонстрация .
Вы также можете добавить error function
, как этот
$timeout(pushA, 5000).then(function(success) {
pushB()
},function(error){console.log("Error");});
При поиске этого ответа я также столкнулся с этой полезной ссылкой
Ответ 3
Как уже упоминалось, ваша большая проблема заключается в том, что вы .then(promise)
, а не .then(function)
.
Promises представляют значение + время. Это результат уже запущенной операции. Обещание - значение - then
ждет функций. Вы не можете "выполнить обещание после другого обещания" - поскольку обещание означает, что операция уже началась.
Когда вы then(x)
для чего-либо, кроме функции, игнорируются. Это неудачный выбор в спецификации promises, но мы должны жить с ним.
Поскольку ваши вызовы синхронны, вы не должны использовать для этого promises. Если ваш код делает что-то синхронное, вы можете выполнять действия с помощью ;
, а не then
:
pushA();
pushB();
Если это вызов, который возвращает promises, тогда он просто становится:
pushA().then(pushB);
Нет смысла вызывать $q.when
, который преобразует не promises в promises.
Я бы написал его как:
pushA();
$timeout(5000).then(pushB);
Нет смысла преобразовывать первое синхронное действие в функцию возврата обещания или включать promises в любом месте, кроме таймаута. Если вам понадобится pushA
, чтобы произойти после 5000 мс, я бы, вероятно, написал:
$timeout(5000).then(pushA).then(pushB)
Так как я думаю, что это более читаемо, и мы снова не связаны с pushA
и pushB
с promises.