在运行摩卡unit testing时,如何避免在NodeJScallback式API中调用两次Q promise catch块?

我们在节点API中使用Q promise库,但允许通过callback调用函数。

例如:

function foo(cb) { Q.fcall(function () { return true; }).then(function (result) { return cb(null, result); }).catch(function (err) { return cb(err, null); }); } 

当我运行我的摩卡单位testing时,如果在callback中有一个exception,它会导致callback被调用两次。

例如:

 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!'); }); 

这给出了以下结果:

err:null res:true调用:1 err:错误:从foo抛出错误! res:null调用:2

我们发现的一个办法是做以下工作:

 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); }); } 

这个想法是有一个地方callback将被调用,并尝试通过强制推迟清除调用堆栈来防止开发人员错误。

使用这种方法,我们的callback被调用一次,任何错误(或在我们的情况下,断言)被调用者直接处理。

有更好的技术可以使用吗? 我觉得这是一个很常见的情况,所以我想可以设想一个更清洁的解决scheme。

修改你的foo函数来处理履行和拒绝在同一个呼叫使用2个独立的处理程序:

 function foo(cb) { Q.fcall(function () { return true; }).then(function (result) { return cb(null, result); }, function (err) { return cb(err, null); }); }