[英]How can I avoid my Q promise catch block being called twice in a NodeJS callback-style API when running mocha unit tests?
We're using the Q promise library in our node API, but allow functions to be called via callbacks. 我们在节点API中使用了Q Promise库,但是允许通过回调调用函数。
For example: 例如:
function foo(cb) {
Q.fcall(function () {
return true;
}).then(function (result) {
return cb(null, result);
}).catch(function (err) {
return cb(err, null);
});
}
When I run my mocha unit tests, if there is an exception in the callback , it results in the the callback being called twice. 当我运行mocha单元测试时,如果回调中存在异常,则会导致回调被调用两次。
For example: 例如:
var called = 0;
foo(function (err, res) {
called++;
console.log('err: ' + err);
console.log('res: ' + res);
console.log('called: ' + called);
throw Error(throw Error from foo!');
});
This gives the following result: 得到以下结果:
err: null res: true called: 1 err: Error: throw Error from foo! err:null res:真调用:1 err:错误:foo抛出错误! res: null called: 2 res:null称为:2
One approach we found was to do the following: 我们发现的一种方法是执行以下操作:
function foo2(cb) {
var _result, _err;
Q.fcall(function () {
return true;
}).then(function (result) {
_result = result;
}).catch(function (err) {
_err = err;
}).finally(function () {
_.defer(cb, _err, _result);
});
}
The idea was to have one place where the callback would be called and try to prevent developer errors by enforcing the defer to clear the call stack. 想法是在一个地方可以调用回调,并通过强制延迟清除调用堆栈来防止开发人员出错。
With this approach, our callback is called once, and any errors (or in our case, asserts) get handled directly by the caller. 使用这种方法,我们的回调将被调用一次,并且任何错误(在我们的情况下是断言)都将由调用方直接处理。
Is there a better technique we can use? 有没有更好的技术可以使用? I feel like this is a pretty common scenario, so I'd imagine there exists a cleaner solution... 我觉得这是一个很常见的情况,所以我想有一个更清洁的解决方案...
Modify your foo
function to handle both the fulfillment and the rejection in the same then
call using 2 separate handlers: 修改foo
函数,以同时处理实现和拒绝, then
使用2个单独的处理程序then
调用:
function foo(cb) {
Q.fcall(function () {
return true;
}).then(function (result) {
return cb(null, result);
}, function (err) {
return cb(err, null);
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.