Q Promises - 创建动态承诺链然后触发它

时间:2014-07-07 23:55:36

标签: promise q

我想知道是否有办法创建一个我可以基于一系列if语句构建的promise链,并以某种方式在最后触发它。例如:

// Get response from some call
callback = (response) {
    var chain = Q(response.userData)

    if (!response.connected) {
        chain = chain.then(connectUser)
    }

    if (!response.exists) {
        chain = chain.then(addUser)
    }

    // etc...

    // Finally somehow trigger the chain
    chain.trigger().then(successCallback, failCallback)
}

2 个答案:

答案 0 :(得分:1)

承诺代表已经开始的操作。您不能trigger()承诺链,因为承诺链已经在运行。

虽然您可以通过创建延迟然后排队并最终解决它来解决这个问题 - 但这不是最佳选择。如果您从最后一行删除.trigger,我怀疑您的任务将按预期工作 - 唯一的区别是它会对操作进行排队并启动它们而不是等待:

var q = Q();
if(false){
    q = q.then(function(el){ return Q.delay(1000,"Hello");
} else {
    q = q.then(function(el){ return Q.delay(1000,"Hi");
}
q.then(function(res){
      console.log(res); // logs "Hi"
});

这里的关键点是:

  • 承诺代表已经开始的操作。
  • 您可以将.then处理程序附加到承诺中,即使它已经解决,它仍然可以预测执行。

祝你好运,编码愉快

答案 1 :(得分:1)

正如本杰明所说......

...但你可能也想考虑一些略有不同的东西。尝试从内到外调整代码;无条件地构建then链并在.then()回调中执行测试。

function foo(response) {
    return = Q().then(function() {
        return (response.connected) ? null : connectUser(response.userData);
    }).then(function() {
        return (response.exists) ? null : addUser(response.userData);//assuming addUser() accepts response.userData
    });
}

我认为如果null无法正常工作,我会逃避返回空值,然后尝试Q()(在两个地方)。

如果我对传递给addUser()的内容的假设是正确的,那么您不必担心将数据传递到链中 - response在外部形成的闭包中仍然可用功能。如果这个假设不正确,那么不用担心 - 只需安排connectUser返回任何必要的内容,然后在第二个.then中选择它。

我认为这种方法比条件链构建更优雅,即使效率较低。那就是说,你不太可能注意到这种差异。