使用Q.deferred

时间:2016-08-09 11:34:21

标签: javascript node.js q deferred

我有一个nodeJS项目,我希望使用异步函数。也就是说,我正在使用Q库。

我有一个名为someFunction()的函数,我希望返回一个promise。使用then -function,我可以检查承诺是否已经解决或被拒绝:

    someFunction()
    .then(
      function(results) {
        console.log("Success!");
      },
      function (error) {
        console.log("An error occurred, and I would wish to log it for example");
      }
    );

我对上述功能的直观期望是,错误功能会捕获所有可能的错误。因此,如果在someFunction中引发了一些异常,我可以放心,将运行错误函数(第二个函数在'然后')。但似乎事实并非如此。

例如,我们假设someFunction定义如下:

function someFunction() {
  var deferred = Q.defer();
  throw new Error("Can't bar.");

  deferred.resolve("success");
}

现在,如果我在上面的代码块中调用函数someFunction(),就不会运行错误函数。这是为什么?不是承诺的部分要点Q.deferred捕捉错误?我为什么要手动拒绝发生的每一个错误?我知道我可以将someFunction的全部内容设置为try / catch子句,然后拒绝延迟,但这感觉错了!必须有一个更好的方法,我肯定知道你们中的一些人知道它了!

有了这些信息,我开始考虑deferred.reject和deferred.resolve在哪里使用?它甚至意味着捕获例外吗?我是否真的只是手动完成所有错误情况,并调用deferred.reject?我很想知道如何以专业方式处理这件事。

4 个答案:

答案 0 :(得分:2)

Q具有成功和错误的特定功能,因此请使用:

deferred.reject("error");

引发异常。

接下来就是 someFunction 必须返回承诺,以便在您使用它时使用:

function someFunction() {

  var deferred = Q.defer();

  try{

  //some Asynchronous code
  deferred.resolve("success");


  }catch(e){

    deferred.reject(e.message);

  }

  return deffered.promise; //return promise to use then
}

答案 1 :(得分:2)

因为承诺是魔法。他们不会以某种方式神奇地捕捉错误。他们捕获它们,因为它们将调用包装在try..catch-blocks中的回调中,以将错误转换为被拒绝的Promises。

如果你想让Promise链处理一个错误,那么把函数调用放到一个promise链中:Q.resolve().then(someFunction).then(...)。 现在,someFunction中出现的任何同步错误都可以在下面处理。

顺便说一句:如果您使用Q.defer(),并且您没有处理某些回调式API,那么您的确做错了。搜索Deferred-antipattern。

答案 2 :(得分:1)

  

它不会运行错误功能。那是为什么?

因为您同步抛出异常,而不是返回承诺。 Which you never should

  

不是承诺的部分要点Q.deferred捕捉错误?

没有。 thencatch隐含地捕获了回调中的例外情况,但是他们并不是一个(deprecated)API来创建承诺。

  

为什么我要手动拒绝发生的每一个错误?

因为异步错误预计会传递给回调,而不是被抛出。

  

我知道我可以将someFunction的全部内容设置为try / catch子句,然后拒绝延迟,但这感觉错了!必须有更好的方法!

Q.Promise constructor,标准(ES6)承诺创建API。它的好处是能够从执行程序函数中捕获同步异常:

function someFunction() {
  return new Q.Promise(function(resolve) {
    throw new Error("Can't bar.");
    resolve("success");
  });
}

答案 3 :(得分:0)

抛出错误将阻止代码执行(并将关闭节点),除非您在try / catch块中捕获错误。

来自请求的

处理错误可以使用.catch传递到deferred.reject(error)链。需要在try / catch中处理代码错误和自定义抛出错误,这是处理此类错误的正确方法。

function someFunction() {
  var deferred = Q.defer();
  deferred.reject("Can't bar.");
  // or
  try {
    throw new Error("Can't bar.");
  }
  catch(err) {
    deferred.reject("Can't bar.");
  }

  deferred.resolve("success");
}