Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Q承诺传播错误和异常_Javascript_Node.js_Error Handling_Q - Fatal编程技术网

Javascript Q承诺传播错误和异常

Javascript Q承诺传播错误和异常,javascript,node.js,error-handling,q,Javascript,Node.js,Error Handling,Q,我使用这段代码是为了将经典的nodejs函数转换为promise函数: Object.defineProperty(Function.prototype, "toPromise", { enumerable: false, configurable: false, writable: false, value: function(self) { var $this; $this = this; return function

我使用这段代码是为了将经典的nodejs函数转换为promise函数:

  Object.defineProperty(Function.prototype, "toPromise", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: function(self) {
      var $this;
      $this = this;
      return function() {
        var arg, args, deferred, _i, _len;
        deferred = Q.defer();
        args = [];
        for (_i = 0, _len = arguments.length; _i < _len; _i++) {
          arg = arguments[_i];
          args.push(arg);
        }
        args.push(function() {
          args = Array.prototype.slice.call(arguments);
          if (args[0] instanceof Error) {
            return deferred.reject.apply($this, args);
          } else {
            return deferred.resolve.apply($this, args);
          }
        });
        $this.apply(self, args);
        return deferred.promise;
      };
    }
  });
但是当抛出我没有抛出的异常(SyntaxError、TypeError…)时,不会调用
then
fail
函数。如何自动传播?

我试着用它来代替toPromise,但这不起作用(即使它与我的函数一起工作时)

我还尝试对
应用第二个回调,然后
,但也没有成功

但是当抛出我没有抛出的异常(SyntaxError、TypeError…)时,不会调用then或fail函数

Q
只捕获从
.then()回调引发的异常。您需要自己明确地处理所有其他异常

如何自动传播

如果从您自己的代码中抛出异常,您可以考虑在较低级别上使用承诺,并将您自己的代码放在<代码> > 只回调。 如果从您调用的“classic nodejs函数”引发异常,则需要捕获它。但是,可能有很好的理由说明为什么会在中抛出异常(这是相当不可恢复的),而不仅仅是使用错误参数调用回调,这将是异步节点函数的“正常”设计方法

如果希望在
toPromise
方法中包含此功能,则需要包装函数调用:

try {
  $this.apply(self, args);
} catch(e) {
  deferred.resolve(e);
}

那是个坏主意。您不应在自己的函数上使用
来实现
,而应仅使用提供给您且具有非承诺接口的函数。请参见教程部分中的“如何生成真正返回承诺的函数”。不要使用
回调
变量。你很容易就漏掉一些错误。特别是如果您有一个已经产生承诺的函数,那么您所需要做的就是在它之后链接其他任务

在你的具体情况下,它只是

exports.list = function(userid, options) {
  return canThis(userid, "mod", "browse").then(function(can) {
    if (can === false)
      throw error.throwError("Forbidden", "UNAUTHORIZED");
    if (options.perPage > 50) {
      throw error.throwError("Too much mods per page", "INVALID_PARAMS");

    var Mod = mongoose.model("Mod");
    return Q.all([ // I would assume that listing and counting can happen in parallel?
      Q.ninvoke(Mod, "list", options),
      Q.ninvoke(Mod.count(), "exec")
    ]).spread(function(mods, count) {
      mods.totalCount = count;
      return mods;
    }, function(err) { // and throw this error when one happens in either?
      throw error.throwError(err, "DATABASE_ERROR");
      // not sure whether you need errors.handleResult at all
      // (not with a callback, at least)
    });
  });
};

现在,所有这些
返回值实际上都是有意义的。

这个
会返回一个承诺(你在上面调用
.then()
),但它被放在一个函数表达式中,你可以手动
toPromise()
然后?什么是
错误。thrower()
?你抓不到的错误在哪里?如果
canThis
接受回调,那么你是指
,函数(can)
而不是
)。然后(函数(can)
?@Bergi不,我犯了一个错误:这是一个承诺,那么你用
回调
做什么
?非常感谢。在一个小测试脚本中,我打印了错误,没有您的代码。但是,在添加行时,输出不同。我将很快在我的应用程序中尝试。为什么我不能在我自己的函数中使用它?它更简单!不幸的是,它不起作用;当我运行一个未定义的函数时,页面加载和加载都不会发生,即使我在解析之前添加了一个console.log(e)不,这并不简单-而且你想使用承诺!你说的“运行未定义的函数”是什么意思?一个更具体的代码示例会更好。
try {
  $this.apply(self, args);
} catch(e) {
  deferred.resolve(e);
}
(function(…, callback) { … }).toPromise(this);
exports.list = function(userid, options) {
  return canThis(userid, "mod", "browse").then(function(can) {
    if (can === false)
      throw error.throwError("Forbidden", "UNAUTHORIZED");
    if (options.perPage > 50) {
      throw error.throwError("Too much mods per page", "INVALID_PARAMS");

    var Mod = mongoose.model("Mod");
    return Q.all([ // I would assume that listing and counting can happen in parallel?
      Q.ninvoke(Mod, "list", options),
      Q.ninvoke(Mod.count(), "exec")
    ]).spread(function(mods, count) {
      mods.totalCount = count;
      return mods;
    }, function(err) { // and throw this error when one happens in either?
      throw error.throwError(err, "DATABASE_ERROR");
      // not sure whether you need errors.handleResult at all
      // (not with a callback, at least)
    });
  });
};