尝试这样的事情:
var bluebird = require('bluebird');function Foo() { }Foo.prototype.method1 = function (cb) { cb(null, 'method1'); };Foo.prototype.method2 = function (cb) { cb(null, 'method2'); };Foo.prototype.method3 = function (cb) { cb(null, 'method3'); };var foo = bluebird.promisifyAll(new Foo());foo.method1Async().then(function (r1) { console.log('step 1'); // cancel then-chain console.log("Task stopped"); // just stop right here return bluebird.reject('some reason');}).then(function (r2) { console.log('step 2'); console.log(r2);}).then(function (r3) { console.log('step 3'); console.log(r3);}).catch(function (er) { console.log('Catch!'); console.log('Error:', er);});代替:
return bluebird.reject('some reason');您可以使用:
throw 'some reason';
结果将是相同的,但是您不想抛出错误,因此您可以返回被拒绝的诺言。
更新1
但是,如果您打算连续运行所有3个方法,则还需要在每个步骤中返回下一个承诺,如下所示:
var bluebird = require('bluebird');function Foo() { }Foo.prototype.method1 = function (cb) { cb(null, 'method1'); };Foo.prototype.method2 = function (cb) { cb(null, 'method2'); };Foo.prototype.method3 = function (cb) { cb(null, 'method3'); };var foo = bluebird.promisifyAll(new Foo());foo.method1Async().then(function (r1) { console.log('step 1'); console.log('got value:', r1); // cancel? change to true: var cancel = false; if (cancel) { console.log("Task stopped"); return bluebird.reject('some reason'); } else { console.log('Keep going'); return foo.method2Async(); }}).then(function (r2) { console.log('step 2'); console.log('got value:', r2); return foo.method3Async();}).then(function (r3) { console.log('step 3'); console.log('got value:', r3);}).catch(function (er) { console.log('Catch!'); console.log('Error:', er);});当前,您问题中的代码将永远不会运行第一个方法以外的任何其他方法。
更新2
catch在这种情况下,另一个不调用最后一个示例:
foo.method1Async().then(function (r1) { console.log('step 1'); console.log('got value:', r1); // cancel? change to true: var cancel = true; if (cancel) { console.log("Task stopped"); return bluebird.reject('some reason'); } else { console.log('Keep going'); return foo.method2Async(); }}).then(function (r2) { console.log('step 2'); console.log('got value:', r2); return foo.method3Async();}).then(function (r3) { console.log('step 3'); console.log('got value:', r3);}).catch(function (er) { if (er === 'some reason') { return bluebird.resolve('ok'); } else { return bluebird.reject(er); }}).catch(function (er) { console.log('Catch!'); console.log('Error:', er);});说明
这样想:在同步代码中,如果您有:
r1 = fun1();r2 = fun2();r3 = fun3();
那么fun1取消执行fun2和fun3的唯一方法是抛出异常。与promise类似,一个
then处理程序可以取消执行下一个处理程序的唯一方法
then是返回被拒绝的promise。就像使用同步代码一样,抛出的异常将被该
catch块捕获,在这里被拒绝的Promise将被传递给
catch处理程序。
使用同步代码,您可以拥有一个内部机制
try/catch来捕获异常,如果该异常不是您用来取消执行的特定异常,则将其重新引发。使用promise,您可以拥有一个更早的
catch处理程序,该处理程序实际上是相同的。
这就是Update 2中的代码所发生的情况。将拒绝原因与某个值进行比较(
'somereason'在该示例中),如果该值相等,则返回已解析的Promise,因此
catch不调用下一个处理程序。如果不相等,则拒绝原因再次返回,因为被拒绝的诺言女巫然后
catch作为您希望最后一个处理程序处理的“实际”错误传递给下一个处理
catch程序。



