kriskowal/q node.js q.all и распространение

У меня есть функция, которой нужен результат трех предыдущих обещаний, переданных ей. Один из них линейно зависим, а два других могут работать одновременно. Я хочу использовать q.all для разрешения трех обещаний, а затем передать результаты четвертому с помощью .spread. Однако мой код не работает. Любая помощь будет оценена по достоинству.

var p1 = doWork(data);
var p2 = p1.then(doMoreWork);
var p3 = doConcurrentWork(data);

return q.all([p1,p2,p3]).spread(funcWith3params)
        .fail(function(err) {
            console.log(err):
        }

Я могу проследить код в инспекторе узлов и увидеть, что вызываются первые 3 промиса. Однако функция, которую вызывает .spread, не вызывается. Любые подсказки относительно того, почему? Также .fail не попадает.


person Daniel Byrne    schedule 12.06.2013    source источник
comment
Я предполагаю, что вы хотели поместить туда закрывающую ).   -  person Sukima    schedule 17.11.2013


Ответы (2)


Распространение вызывает q.all внутренне.

Вот код спреда из q.js:

Q.spread = spread;
function spread(promise, fulfilled, rejected) {
    return when(promise, function (valuesOrPromises) {
        return all(valuesOrPromises).then(function (values) {
            return fulfilled.apply(void 0, values);
        }, rejected);
    }, rejected);
}

Обратите внимание, что он ожидает обещание, которое разрешается в массив или массив в качестве первого аргумента.

Поэтому ваш вызов должен выглядеть так:

var p1 = doWork(data);
var p2 = p1.then(doMoreWork);
var p3 = doConcurrentWork(data);

return q.spread([p1,p2,p3], funcWith3params, function(err) {
        console.log(err):
    });

Однако ваш первоначальный вызов также должен работать. Не уверен, почему это не так.

person Nathan    schedule 12.06.2013

Самый краткий способ выразить приведенный вами пример:

var p1 = doWork(data);
var p2 = p1.then(doMoreWork);
var p3 = doConcurrentWork(data);

return Q.spread([p1, p2, p3], funcWith3params)
    .done();

Тем не менее, оригинал верен, как написано.

Я подозреваю, что проблема в том, что одно или несколько входных обещаний никогда не разрешаются. Попробуйте использовать тайм-ауты, чтобы изолировать проблему.

var p1 = doWork(data).timeout(1000, 'p1 timed out');
var p2 = p1.then(doMoreWork).timeout(1000, 'p2 timed out');
var p3 = doConcurrentWork(data).timeout(1000, 'p3 timed out');

return Q.spread([p1, p2, p3], funcWith3params)
   .done();
person Kris Kowal    schedule 12.06.2013
comment
Я видел использование .done() без аргументов и несколько примеров с аргументами. Есть ли разница и / или лучшая практика? - person Sukima; 17.11.2013
comment
@Sukima done() используется для явного закрытия цепочки обещаний, т. е. вы не можете ожидать, что больше обработчиков then сработает после вызова done. - person Renaud; 13.11.2014