jQuery deferred:在fail()回调中抛出并捕获异常



我正在尝试发出ajax请求,并在失败时抛出异常。不幸的是,我没能抓住这个例外。我的代码如下:

try {
    jQuery.ajax('http://www.someurlthatwillproduceanerror.com')
        .fail(function () {
            throw 'an exception';
        })
        .done(function () {
            console.log('ok');
        })
    ;
} catch (e) {
    console.log(e);
}

我希望代码能够捕获异常并将"异常"记录到控制台。相反,我最终得到了一个未捕获的异常。

有人知道在这种情况下如何处理异常吗?

不,你不能那样做。这不是promise的异常处理方式。

done子句中的代码不会与try/catch在同一时间或上下文中执行。您还不能在浏览器中异步捕获这样的异常。

我的建议是.fail子句视为捕获

jQuery.ajax('http://www.someurlthatwillproduceanerror.com')
    .fail(function () {
        console.log("an exception"); // the handler here!
    })
    .done(function () {
        console.log('ok');
    });

请注意,基于异常执行某些操作的代码不必与声明promise的代码位于同一位置。

var p = jQuery.ajax('http://www.someurlthatwillproduceanerror.com');
... 
...
p.fail(function(){ /* I'm handling it here */}); // .catch in modern promise libs

一般来说,从处理promise的函数中返回promise可能是个好主意——这通常会产生更干净的代码。

您提供的抛出异常的fail函数是异步执行的。

我假设您想向调用方传播一个错误,因此,考虑到这一点,您应该知道延迟故障是为了根据定义对此进行建模而设计的(向上传播故障,异步发生的故障除外)。

您应该将延迟的promise返回给调用者,然后调用者可以附加自己的成功/失败回调,而不是依赖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.'); });

也许您正试图将所有错误处理代码放在一个地方。如果是这样,您可以利用jQuery的ajax方法(或get或其他方法)实现promise接口的事实,并将任何有风险的代码放入then函数中。

方法如下:

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

这样,无论是在服务器端还是客户端,您都有一个fail()函数来处理任何意外错误。

最新更新