2014-07-07 36 views
2

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

// 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) 
} 

回答

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处理程序附加到承诺,并且仍然可以执行预测。

祝你好运,快乐编码

+0

是的,我试过了,我发现它是我的代码中的另一个错误,它阻止了它的工作。修正了这一切,它全是绿色的:) – Maruf

1

正如本雅明说...

...但你可能也想考虑的东西略有不同。尝试从内向外翻译代码;无条件地构建当时的链,并在.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中选择它。

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