2014-12-05 3 views
2

Я хочу сделать что-то очень простое, но я не понимаю, мелочи ...Nodejs/Q: СЦЕПЛЕНИЕ обещает последовательно

var Q = require('q'); 

var funcs = ["first", "second", "third", "fourth"]; 

function main(){ 

// really don't know how to chain sequentially here ... 
    var result = Q(); 

    funcs.forEach(function (f) { 
     result = treat(f).then(f); 
    }); 

} 

function treat(t){ 

    var deferred = Q.defer(); 

    setTimeout(function(){ 
     deferred.resolve("treated "+ t); 
    },2000); 

    return deferred.promise; 
} 

main(); 

Я хотел бы, чтобы каждый элемент моего массива funcs быть «лечение "последовательно, выход затем будет что-то вроде:

treated first 
//2 seconds later 
treated second 
//2 seconds later 
treated third 
//2 seconds later 
treated fourth 

я не могу добиться, что :(это должно быть просто, я не поймать что-то :(

ответ

8

Судя из вашего примера, я предположил бы, что вы alr eady увидел Sequences part of Q readme, но не понял.

Оригинальный пример используется модель «водопад», когда на выходе из каждой функции передается в качестве входных данных для следующего:

var funcs = [foo, bar, baz, qux]; 

var result = Q(initialVal); 
funcs.forEach(function (f) { 
    result = result.then(f); 
}); 
return result; 

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

var args = ["first", "second", "third", "fourth"]; 

var result = Q(); 
args.forEach(function (t) { 
    result = result.then(treat.bind(null, t)); 
}); 
return result; 

в моем примере treat функция будет вызываться в 4 раза последовательно, и result обещание будет решена со значением последних treat вызовов (результаты всех предыдущие вызовы будут проигнорированы).

Хитрость в том, что метод .then принимает обработчик, который будет называться после того, как текущее обещание будет разрешено, и возвращает новое обещание. Итак, вы должны передать .then функцию, которая должна быть вызвана на следующем шаге вашей цепочки выполнения. treat.bind(null, t) связывает treat функция с атрибутом t. Другими словами, он возвращает новую функцию, которая будет вызывать treat, передавая t в качестве своего первого аргумента.

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