如何正确地放弃使用Q的node.js诺言链?

我为Node.js使用了Q模块 ,试图避免在我有很多步骤的场景中的“厄运金字塔”。 例如:

function doTask(task, callback) { Q.ncall(task.step1, task) .then(function(result1){ return Q.ncall(task.step2, task); }) .then(function(result2){ return Q.ncall(task.step3, task); }) .fail(callback).end(); } 

基本上这似乎工作; 如果任何一个任务步骤都抛出了错误,那么就会传递给callback函数(尽pipe我很乐意进行改进,因为我是node.js promise的新手)。 但是,当我需要尽早中止任务链时,我遇到了一个问题。 例如,如果result1被成功返回,我可能想要尽早调用callback函数,然后放弃其余的函数,但是我的尝试失败了。

 function doTask(task, callback) { Q.ncall(task.step1, task) .then(function(result1){ if(result1) {// the rest of the task chain is unnecessary console.log('aborting!'); callback(null, result1); return null; } return Q.ncall(task.step2, task); }) .then(function(result2){ console.log('doing step 3...'); return Q.ncall(task.step3, task); }) .fail(callback).end(); } 

在这个例子中,我看到“中止!” 和“做第3步…”打印。

我相信我只是误解了这里的一些基本原则,所以感谢你的帮助。 谢谢!

在promise链中引发的任何错误都会导致整个堆栈提前中止,并将控制权交给错误返回path。 (在这种情况下,失败()处理程序)当你检测到一个特定的状态,导致你想中止承诺链,然后只是抛出一个非常具体的错误,你陷入错误,并忽略(如果你这样select)

 function doTask(task, callback) { Q.ncall(task.step1, task) .then(function(result1){ if(result1 == 'some failure state I want to cause abortion') {// the rest of the task chain is unnecessary console.log('aborting!'); throw new Error('abort promise chain'); return null; } return Q.ncall(task.step2, task); }) .then(function(result2){ console.log('doing step 3...'); return Q.ncall(task.step3, task); }) .fail(function(err) { if (err.message === 'abort promise chain') { // just swallow error because chain was intentionally aborted } else { // else let the error bubble up because it's coming from somewhere else throw err; } }) .end(); } 

这是你需要分支的情况,这意味着嵌套或创build一个子程序。

 function doTask(task, callback) { return Q.ncall(task.step1, task) .then(function(result1) { if (result1) return result1; return Q.ncall(task.step2, task) .then(function(result2) { return Q.ncall(task.step3, task); }) }) .nodeify(callback) } 

要么

 function doTask(task, callback) { return Q.ncall(task.step1, task) .then(function(result1) { if (result1) { return result1; } else { return continueTasks(task); } }) .nodeify(callback) } function continueTasks(task) { return Q.ncall(task.step2, task) .then(function(result2) { return Q.ncall(task.step3, task); }) } 

我相信你只需要拒绝承诺摆脱承诺链。

https://github.com/kriskowal/q/wiki/API-Reference#qrejectreason

也似乎.end()已经改为.done()

 function doTask(task, callback) { Q.ncall(task.step1, task) .then(function(result1){ if(result1) {// the rest of the task chain is unnecessary console.log('aborting!'); // by calling Q.reject, your second .then is skipped, // only the .fail is executed. // result1 will be passed to your callback in the .fail call return Q.reject(result1); } return Q.ncall(task.step2, task); }) .then(function(result2){ console.log('doing step 3...'); return Q.ncall(task.step3, task); }) .fail(callback).done(); }