然后在里面使用cancel()
不知道如果我用这个标题不够清晰,但假设我有一个叫富带班method1
, method2
和method3
。 我promisify与方法promisifyAll
。
然后我有一个then-chain,我想在第二个或第一个中间取消操作,然后不应该再调用。
我阅读了取消(http://bluebirdjs.com/docs/api/cancellation.html),但我不知道如何使用promisifyAll实现它。
我得到的代码加上我需要的:
var bluebird = require('bluebird');
function Foo() { }
Foo.prototype.method1 = function (cb) {};
Foo.prototype.method2 = function (cb) {};
Foo.prototype.method3 = function (cb) {};
var foo = bluebird.promisifyAll(new Foo());
foo.method1Async()
.then(function (r1) {
// cancel then-chain
res.json("Task stopped");
// just stop right here
promises.cancel();
})
.then(function (r2) {
console.log(r2);
}).then(function (r3) {
console.log(r3);
})
.catch(function (er) {
console.log('Catch!');
});
有这个结果的正确方法是什么? 我知道我可以抛出一些东西并用catch
方法捕捉它,但是这会对我的真实代码做出很大的改变。
尝试这样的事情:
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的唯一方法就是抛出一个异常。 同样地,对于承诺,一个唯一的方法then
处理可能取消下一次的执行then
处理程序返回一个拒绝承诺。 就像使用同步代码抛出异常将被catch
块catch
,这里被拒绝的promise将被传递给catch
处理程序。
使用同步代码,您可以拥有一个内部try/catch
捕获异常,并在它不是您用来取消执行的特定异常时重新引发异常。 有了承诺,你可以拥有一个早期的catch
处理程序,它的功能基本相同。
这就是Update 2中的代码所发生的情况。拒绝原因与某个值(在该示例中为'some reason'
)相比较,如果相等则返回已解析的promise,因此未调用下一个catch
处理程序。 如果不相等,则拒绝理由再次返回然后拒绝承诺女巫传递到下一个catch
处理程序,您希望这最后一个“真实”的错误catch
处理程序来处理。