使用Q.promise时处理异常的最佳实践

时间:2014-10-29 16:33:14

标签: javascript node.js promise q

我有以下方法:

module.exports.getId = function(someObject) {

    var myId = null;

    return Q.Promise(function(resolve, reject, notify) {

        // Loop through all the id's
        someObject.user.player._id.forEach(function (id) {

            if (id.root == "1.2.3.4.5.6") {
                myId = id.extension;
            }
        });

        resolve(myId);
    });
};

只要someObject存在并具有user.player._id属性,此方法就可以正常运行。

我遇到的问题是,如果someObject为空或者没有所有适当的嵌套属性,则抛出异常并且永远不会解析承诺。我实际看到异常的唯一方法是,如果我在调用函数上有一个.fail,但它仍然没有真正解决这个问题。

我目前如何看到异常的示例:

myLib.getId.then(function() {
  // something
}).fail(function(err) {
  console.log(err);
});

我知道有两种方法可以解决这个问题,但我不知道哪种方法可以解决这个问题。

选项1(在我的Q.promise中使用try / catch):

module.exports.getId = function(someObject) {

    var myId = null;

    return Q.Promise(function(resolve, reject, notify) {

      try {
        // Loop through all the id's
        someObject.user.player._id.forEach(function (id) {

            if (id.root == "1.2.3.4.5.6") {
                myId = id.extension;
            }
        });

      } catch(e) {
        reject(e);
      }

      resolve(myId);
    });
};

选项2(明确检查someObject.user.player._id是否存在):

module.exports.getId = function(someObject) {

    var myId = null;

    return Q.Promise(function(resolve, reject, notify) {

      ifi(someObject.user.player._id exists..) {

        // Loop through all the id's
        someObject.user.player._id.forEach(function (id) {

            if (id.root == "1.2.3.4.5.6") {
                myId = id.extension;
            }
        });

        resolve(myId);
      } else {
        reject('invalid object');
      }
    });
};

选项1似乎对我来说很时髦,因为我在承诺中使用了try / catch。选项2解决了我的问题,但任何其他意外的异常都不会被捕获。

我有更好的方法来处理这个问题吗?

1 个答案:

答案 0 :(得分:-1)

你的第一个例子有一些问题:

  • 当你发现异常时,你拒绝承诺,然后解决承诺。这违反了承诺合同;您可以通过在try内调用resolve来解决问题,而不是在外面。
  • 通过使用try / catch,您可能会吞下意外错误。那就是你假设唯一的错误来自someObject.user.player._id不存在。目前可能是这样,但随着代码的发展,它不能保证保持真实。

通过准确测试已知错误情况,您知道您不会吞下意外错误。因此,我会使用你的第二个例子。