我只是转而接受承诺,我确定我遇到了问题,但我无法弄清楚是什么。
在下面的代码中,如果_getDevice()返回null(它是引擎盖下的mongodb.findOneAsync()
),我想取消这个承诺。
从我的角度来看,如果_getDevice返回null,那么应该取消承诺,我应该看到' CANCEL REPLY'登录。但相反,我得到了“保存回复”#39;登录。
我正在使用蓝鸟图书馆。
var promise = Promise.props({
device: _getDevice(event.deviceId),
events: _getEvents(event.deviceId, event.date)
}).cancellable();
promise.then(function (result) {
if (! result.device) {
return promise.cancel()
}
var device = new Device(result.device);
var events = result.events;
// ...
return db.collection(collections.devices).saveAsync(device.toMongoDocument());
}).then(function () {
console.log('SAVE REPLY');
return req.reply(null);
}).catch(Promise.CancellationError, function (err) {
console.log('CANCEL REPLY')
return req.reply(null);
}).catch(function (error) {
return req.reply(error);
});
答案 0 :(得分:4)
您无法取消then
回调中的承诺,因为执行该回调意味着承诺已经解决。之后改变状态是不可能的。
您可能想要做的是从处理程序中抛出错误,从而导致拒绝从then()
返回的新承诺。
您甚至可以在加入两个promise之前执行此操作,以便getEvents
承诺在getDevice
承诺失败时取消:
Promise.props({
device: _getDevice(event.deviceId).then(function(device) {
if (!device)
throw new Promise.CancellationError(); // probably there's a better error type
else
return new Device(device);
},
events: _getEvents(event.deviceId, event.date) // assuming it is cancellable
}).then(function (result) {
var device = result.device;
var events = result.events;
// ...
return db.collection(collections.devices).saveAsync(device.toMongoDocument());
}).then(function () {
console.log('SAVE REPLY');
return req.reply(null);
}).catch(Promise.CancellationError, function (err) {
console.log('CANCEL REPLY')
return req.reply(null);
}).catch(function (error) {
return req.reply(error);
});
答案 1 :(得分:0)
我不认为接受的答案是完全正确的;请参阅Cancelling Long Promise Chains - 可以取消then()
内的承诺。但是我不确定原问题到底是什么问题(行为没有真正描述过)。
尝试将.cancellable()
放在第二个承诺的末尾。