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');
}
});
};