我有一个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?我很想知道如何以专业方式处理这件事。
答案 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捕捉错误?
没有。 then
和catch
隐含地捕获了回调中的例外情况,但是他们并不是一个(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");
}