javascript jQuery 延迟:在 fail() 回调中抛出并捕获异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20092738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery deferred: throw and catch an exception in the fail() callback
提问by Nikolas
I am trying to make an ajax request and throw an exception when it fails. Unfortunately I am not able to catch the exception. My code looks like this:
我正在尝试发出 ajax 请求并在失败时抛出异常。不幸的是,我无法捕捉到异常。我的代码如下所示:
try {
jQuery.ajax('http://www.someurlthatwillproduceanerror.com')
.fail(function () {
throw 'an exception';
})
.done(function () {
console.log('ok');
})
;
} catch (e) {
console.log(e);
}
I would expect the code to catch the exception and log 'an exception' to the console. Instead I end up with an uncaught exception.
我希望代码能够捕获异常并将“异常”记录到控制台。相反,我最终遇到了一个未捕获的异常。
Does anyone know how to handle exceptions in this case?
有谁知道在这种情况下如何处理异常?
采纳答案by Benjamin Gruenbaum
No, you can't do that. That's not how exception handling works with promises.
不,你不能那样做。这不是异常处理与 Promise 的工作方式。
The code inside the done
clause is not executed in the same time or context as the try/catch. You can't asynchronously catch exceptions like that (yet!) in the browser.
done
子句中的代码与 try/catch 不在同一时间或上下文中执行。你不能在浏览器中异步捕获这样的异常(还!)。
My suggestion is treatthe .fail
clause as the catch.
我的建议是把该.fail
条款为续。
jQuery.ajax('http://www.someurlthatwillproduceanerror.com')
.fail(function () {
console.log("an exception"); // the handler here!
})
.done(function () {
console.log('ok');
});
Note that the code that does something based on the exception does not have to be in the same place as the code declaring the promise.
请注意,基于异常执行某些操作的代码不必与声明承诺的代码位于同一位置。
var p = jQuery.ajax('http://www.someurlthatwillproduceanerror.com');
...
...
p.fail(function(){ /* I'm handling it here */}); // .catch in modern promise libs
In general, it might be a good idea to return the promise from functions that deal with promises - that usually produces cleaner code.
一般来说,从处理承诺的函数中返回承诺可能是一个好主意——这通常会产生更清晰的代码。
回答by Ezekiel Victor
The fail
function you provide that throws the exception is executed asynchronously.
fail
您提供的引发异常的函数是异步执行的。
I'm assuming you wanted to propagate up an error to the caller, so given that, you should know that deferred failure is designed to model this by definition (propagating up a failure, except one that occurs asynchronously).
我假设您想将错误传播给调用者,因此,鉴于此,您应该知道延迟失败旨在根据定义对此进行建模(传播失败,异步发生的失败除外)。
You should return the deferred promise to the caller and the caller can then attach its own success/fail callbacks instead of relying on try/catch. Here's sample generic Deferred use:
您应该将延迟的承诺返回给调用者,然后调用者可以附加自己的成功/失败回调,而不是依赖于 try/catch。以下是通用延迟使用示例:
function yourFunc() {
return jQuery.ajax('http://www.someurlthatwillproduceanerror.com')
.done(function () {
console.log('ok');
});
}
yourFunc().fail(function() { console.log('this... instead of a try/catch.'); });
回答by Michael Scheper
Perhaps you're trying to put all your error-handling code in one place. If so, you can take advantage of the fact that jQuery's ajaxmethod (or getor whatever) implements the promiseinterface, and put any risky code in a thenfunction.
也许您正试图将所有错误处理代码放在一个地方。如果是这样,您可以利用jQuery 的ajax方法(或get或其他方法)实现promise接口这一事实,并将任何有风险的代码放入then函数中。
Here's how:
就是这样:
jQuery.ajax('http://www.someurlthatwillproduceanerror.com/but/only/maybe')
.then(function(data, textStatus, jqXHR) {
// This function handles the response. It is NOT called if the AJAX fails.
console.log('ok');
/** An optional result object to pass to your done() function */
var result;
try {
// Code that might blow up goes here
result = 'The final result';
} catch (e) {
// Oh no—it blew up!
// Reject the promise with the function signature of an AJAX failure
return $.Deferred().reject(jqXHR, textStatus, e);
}
// We only get this far if there wasn't an exception.
return result; // Optional
})
.done(function(result) {
// This function gets called if there were no problems at all.
alert('Well, that\'s just ducky! Contact the vendor ' +
'and tell them to promote their devs!');
console.log('Woo-hoo!', result);
})
.fail(function(jqXHR, textStatus, errorThrown) {
// This function gets called if the AJAX failed, or if there was an exception
alert('Something went wrong. Contact the vendor ' +
'and tell them to give their devs more money!');
console.error('Rats!', jqXHR, textStatus, errorThrown);
});
This way, you have one fail() function for any unexpected error, whether it's on the server side or client side.
这样,无论是在服务器端还是客户端,对于任何意外错误,您都有一个 fail() 函数。