用Q.deferred捕获错误
我有一个nodeJS项目,我希望使用asynchronousfunction。 也就是说,我正在使用Q库。
我有一个叫做someFunction()的函数,我希望返回一个promise。 有了这个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内部引发一些exception,我可以放心,错误函数将会运行('then'之后的第二个函数)。 但似乎并非如此。
例如,假设someFunction将被定义如下:
function someFunction() { var deferred = Q.defer(); throw new Error("Can't bar."); deferred.resolve("success"); }
现在,如果我像调用上面的代码块一样调用someFunction()函数,它将不会运行错误函数。 这是为什么? Q.承诺错误的部分是不是错误? 为什么我应该手动拒绝发生的每一个错误? 我知道我可以将someFunction的全部内容设置为try / catch子句,然后拒绝这个延期的,但是那个感觉是错误的! 必须有更好的办法,我知道你们中有些人可以知道它!
有了这些信息,我开始思考deferred.reject和deferred.resolve是甚么意思呢? 这是否意味着要捕捉exception? 我真的应该手动通过所有的错误情况,并调用他们的deferred.reject? 我很想听听这个应该如何处理专业。
它不会运行错误function。 这是为什么?
因为你同步抛出一个exception,而不是返回一个承诺。 你从来不应该这样做 。
Q.承诺错误的部分要点是不是?
不, then
在callback中隐式捕获exception,defferred不会 – 它们只是一个( 不赞成使用的 )API来创buildpromise。
为什么我应该手动拒绝发生的每一个错误?
因为asynchronous错误预计会传递给callback,而不是被抛出。
我知道我可以将someFunction的全部内容设置为try / catch子句,然后拒绝这个延期的,但是那个感觉是错误的! 一定会有更好的办法!
有: Q.Promise
构造函数 ,标准(ES6)promise创buildAPI。 它具有能够从执行程序函数捕获同步exception的好处:
function someFunction() { return new Q.Promise(function(resolve) { throw new Error("Can't bar."); resolve("success"); }); }
Q具有成功和错误的特定function,所以使用:
deferred.reject("error");
扔一个例外。
接下来的事情是, 一些function必须返回承诺,使用它时使用它:
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 }
因为承诺不是魔术。 他们不会奇迹般地捕捉错误。 他们捕捉它们,因为它们将try..catch-blocks中的callback包装到callback中,将错误转换为拒绝的Promise。
如果你想让一个错误被Promise链处理,那么把函数调用放到一个promise链中: Q.resolve().then(someFunction).then(...)
。 现在在某些函数中发生的任何同步错误都可以在下面的处理。
顺便说一句:如果你使用Q.defer(),而你没有处理一些callback式的API,你肯定是做错了。 search延迟反模式。
抛出一个错误会阻止代码执行(并将closures节点),除非您在try / catch块中捕获错误。
可以通过使用deferred.reject(error)
将处理的来自请求的错误传递给.catch
链。 代码错误和自定义抛出的错误需要在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"); }