在返回之前在功能中收集Q Promise

时间:2014-02-26 20:52:29

标签: javascript node.js promise q

我有一个使用promises和Q库的函数,基本上我想等到所有的promises在返回之前都被强制执行,但我的代码才刚刚落实:

function makeSomething(){

        var something = new Something()

    Q.all([

        somethingPromise1(something)
        , somethingPromise2(something)

    ]).spread(function(resultsFromP1, resultsFromP2){

        something.otherValue =  resultsFromP2

    }).done()

    return something
}

var something = makeSomething()
console.log(something.otherValue)

代码更复杂,但这是要点。调用它更像是

something = _.find(things, function(){})
if(!something ) something  = makeSomething()

然后

manyMoreInterestingTasks(something)

我不希望我的调用代码必须在if上分叉。基本上我希望makeSomething在它返回之前一直阻塞。我是Node和Q的新手,所以如果我滥用这种方法,我会道歉......

1 个答案:

答案 0 :(得分:1)

  

基本上我希望makeSomething在它返回之前一直阻塞。

It's impossible同步获取Promise的结果。 othervalue属性是异步创建的,但您立即返回something。更好:

function makeSomething(){
    return Q.all([
        somethingPromise1(something),
        somethingPromise2(something)
    ]).spread(function(resultsFromP1, resultsFromP2){
        var something = new Something(resultsFromP1);
        something.otherValue = resultsFromP2;
        return something;
    });
}

你需要把你的整个代码放在承诺中!然而,这并不像听起来那么复杂:

// Quite narrative actually (the "then" even was in you question already :-) ):
Q(_.find(things,function(){}) || makeSomething()).then(manyMoreInterestingTasks);

// More verbose version of above:
var something = _.find(things, function(){});
var promiseForSomething = something ? Q(something) : makeSomething();
promiseForSomething.then(function(something) {
    manyMoreInterestingTasks(something);
});

// Similar thing within the chain:
Q( _.find(things, function(){}) ).then(function(something) {
    // returning either a promise or a plain value from the callback
    if (!something)
        return makeSomething();
    else
        return something;
}).then(manyMoreInterestingTasks);

// With explicit error propagation and recovery:
function findSomething() {
    var something = _.find(things, function(){});
    if (something)
        return Q(something);
    else
        return Q.reject("couldn't find anything");
}
findSomething().catch(makeSomething).then(manyMoreInterestingTasks);