Javascript 在运行mocha单元测试时,如何避免在NodeJS回调样式API中调用两次Q promise catch块?

Javascript 在运行mocha单元测试时,如何避免在NodeJS回调样式API中调用两次Q promise catch块?,javascript,node.js,promise,mocha.js,q,Javascript,Node.js,Promise,Mocha.js,Q,我们在节点API中使用Q promise库,但允许通过回调调用函数 例如: function foo(cb) { Q.fcall(function () { return true; }).then(function (result) { return cb(null, result); }).catch(function (err) { return cb(err, null); }); } var called = 0; foo(function (err,

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

例如:

function foo(cb) {
 Q.fcall(function () {
    return true;
 }).then(function (result) {
    return cb(null, result);
 }).catch(function (err) {
    return cb(err, null);
 });
}
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!');
});
当我运行mocha单元测试时,如果回调中存在异常,则会导致回调被调用两次

例如:

function foo(cb) {
 Q.fcall(function () {
    return true;
 }).then(function (result) {
    return cb(null, result);
 }).catch(function (err) {
    return cb(err, null);
 });
}
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!');
});
这将产生以下结果:

错误:空 res:是的 电话:1 错误:错误:从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);
  });
}
其想法是在一个地方调用回调,并通过强制执行defer清除调用堆栈来防止开发人员出错

使用这种方法,我们的回调被调用一次,任何错误(或者在我们的例子中是断言)都直接由调用方处理


我们有没有更好的方法?我觉得这是一个非常常见的场景,所以我可以想象存在一个更干净的解决方案…

修改您的
foo
函数,在同一
中处理履行和拒绝,然后使用两个单独的处理程序调用:

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

err:null res:true调用:1 err:Error:throw Error from foo!res:null调用:2
No,这正是我想要避免的。回调应该从foo调用一次。在第一种情况下,它在成功运行时被调用一次,然后在遇到错误时再次被调用,因为promise-catch块仍然具有控制权