Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.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.promise时处理异常的最佳实践_Javascript_Node.js_Promise_Q - Fatal编程技术网

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

Javascript 使用Q.promise时处理异常的最佳实践,javascript,node.js,promise,q,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

我有以下方法:

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.\u id属性,该方法就非常有效

我遇到的问题是,如果someObject为null或没有所有适当的嵌套属性,就会抛出异常,承诺永远不会得到解决。我实际看到异常的唯一方法是调用函数时出现.fail,但这仍然不能解决承诺

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

myLib.getId.then(function() {
  // something
}).fail(function(err) {
  console.log(err);
});
我知道解决这个问题的两种方法,但我不确定哪一种是最好的方法

选项1在我的Q承诺中使用try/catch:

选项2明确检查someObject.user.player.\u id是否存在:

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


是否有更好的方法处理此问题?

您的第一个示例存在一些问题:

当您发现异常时,您拒绝了承诺,然后解决了承诺。这违反了合同的承诺;您可以通过在try内部而不是外部调用resolve来解决这个问题。 通过使用try/catch,您可能会接受意外错误。也就是说,您假设唯一的错误来自someObject.user.player.\u id不存在。目前这可能是正确的,但不能保证在代码发展过程中保持正确。
通过精确地测试已知的错误条件,您知道您不会接受意外错误。因此,我将使用您的第二个示例。

不是downvoter,但我想知道-为什么您首先在同步代码中使用承诺?另外,如果你使用承诺,抛出和拒绝是一样的。我在同步代码b/c中使用承诺,它是库的一部分,我不想让用户知道库中的哪些方法是同步的,哪些不是,所以我让它们都是异步的。我知道投掷和拒绝是一样的。我并不是真的抛出任何东西。当然你是——当你做a.b.c.。在不知道有什么的情况下,你正在编写代码,可能会抛出,这样捕获后的rejext充其量是冗余的。如果我错了,请纠正我,但捕获内的拒绝不是冗余的b/c在我非常具体的情况下,一个异常显然是在我看到后引发的[TypeError:无法读取null的属性'user']在我的日志中,但承诺从未被拒绝或解决,因此它只是挂起。请创建一个小提琴来说明此问题。@downvoter请解释DownVorts,以便我可以删除/改进答案不是我,但我不知道这是如何解决问题的,除了我的意见,我相信你可以写一个解释pr的答案OP设计中的问题,然而,目前的答案不是很好-不值得否决,但仍然是。@JuanMendes,只有在错误没有被收回或返回时才会尝试/捕获吞咽错误。我知道你的意思,但对我来说,这不是你想要捕获的类型,而是你想要捕获时处理的类型,以及你如何处理任何未处理的东西d、 既然你可以选择,就像在问题中一样,不处理catch条款中的任何错误,那么无条件地重新承诺或拒绝承诺是完全有效的。因此,任何错误,而不仅仅是你预测的错误,都可以在其他地方处理/重新承诺。简言之,拒绝保证不吞咽任何东西,我并不是说具体的安全性是有限的一件坏事,就是你不应该对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);
    });
};
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');
      }
    });
};