Проблемы с использованием циклов for с последовательными промисами (q)

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

Я думал, что это может быть похоже на эту ссылку, но я думаю, что объявляю функцию, а не вызываю ее в объявлении then? Как последовательно запускать обещания с Q в Javascript?

Ожидаемый результат:

starting: 3 
ending: 3
starting: 2 
ending: 2
starting: 1  
ending: 1 

Фактический результат:

starting: 3 
starting: 2 
starting: 1 
ending: 1 
ending: 2 
ending: 3 

http://jsfiddle.net/4k6t9/3/

var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope, $q, $timeout) { 
   var temp = $q.when({});
   var arr = [3, 2, 1];

    arr.forEach(function(element) {
        temp = temp.then(delay(element));
    })

    function delay(timing) {
        var deferred = $q.defer();
        console.log('starting: ' + timing)
        $timeout(function() {
            console.log('ending: ' + timing);
            deferred.resolve(timing);
        }, timing * 1000);
        return deferred.promise;
    }
});

person Dan Tang    schedule 04.09.2013    source источник


Ответы (1)


Ваша скрипка немного отличается от кода в вопросе. Но вы где почти там. Отсутствовал только один оператор возврата.

Вы правы: temp = temp.then(delay(element)); звонит delay. Вместо этого вы хотите вернуть функцию, которая вызовет delay. (У вас было это в скрипке.)

Единственное, чего не хватало, так это return для возврата :)

Вот рабочая скрипта: http://jsfiddle.net/4k6t9/6/

person Scheintod    schedule 04.09.2013
comment
@DanTang Мне нравится использовать reduce для создания последовательности обещаний: jsfiddle.net/czU8L/1 - person Scott Christopherson; 28.01.2014