2013-11-20 41 views
4

我想做一個ajax請求,並在失敗時拋出異常。不幸的是,我無法捕捉到這個例外。我的代碼如下所示:jQuery推遲:在失敗()回調拋出和捕獲異常

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

我希望代碼捕捉異常並將「異常」記錄到控制檯。相反,我最終得到一個未捕獲的異常。

有沒有人知道在這種情況下如何處理異常?

+0

對不起......它不會像工作,因爲你是在處理異步執行 –

回答

2

不,你不能這樣做。這不是異常處理如何與承諾協同工作的。

done子句中的代碼不是在相同的時間或歷境作爲嘗試/捕獲執行。您不能在瀏覽器中異步捕獲像那樣的異常(還!)。

我的建議是治療.fail條款爲續

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

請注意,基於異常執行某些操作的代碼不必與聲明承諾的代碼位於同一位置。

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

一般來說,從處理promise的函數中返回promise可能是個好主意 - 通常會產生更乾淨的代碼。

+0

「這不是異常處理如何與承諾工作」 - 這是一個過於寬泛的說法。這僅僅是「jQuery異常處理」的工作原理。 ECMAScript承諾允許從處理程序冒泡到處理程序,處理程序允許通用捕獲處理程序以及下游處理程序。 – Todd

+0

@Todd不,它不是,這是關於向承諾鏈外部的_synchronous_代碼冒泡 - 這是行不通的,因爲承諾代碼是異步運行的。這根本不是語言的工作原理 - 你可以使用異步函數讓你「等待」事物 - 但是這改變了規則:) –

+0

這不是關於冒泡到同步代碼,而是你剛纔說的。讀他的第一句話。他的代碼是回答可能看起來像的一個例子,它不會限制要求同步阻止的答案。你的答案也不涉及同步catch塊。看到我的答案,看看我的意思,是一個很好的候選人爲未來的參考。 – Todd

1

您提供的fail函數異常執行異常執行。

我假設你想傳播一個錯誤給調用者,因此,你應該知道,延期失敗的目的是通過定義對這個模型進行建模(傳播失敗,除非是異步發生的失效)。

您應該推遲承諾返回給調用者,然後調用者可以將自己的成功/失敗的回調,而不是依靠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.'); }); 
0

也許你正試圖把所有的錯誤處理代碼放在一個地方。如果是這樣,您可以利用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); 
    }); 

這樣一來,你有任何意外的錯誤一個失敗()函數,無論是在服務器端或客戶端。

+0

參考:http://stackoverflow.com/a/17805506/1450294 –

+1

不明原因的反對票是StackExchange世界的unannotated一星級應用程序評級。 –

+1

那你去吧。其實,在jQuery 3(至少)中,你可以從THEN處理程序中拋出一個異常,並且它會冒泡。我嘗試了這裏的方法(並引用您的註釋鏈接),它的工作原理,除了它適用於自然發生的異常,這使我認爲它可能適用於明確拋出的異常 - 它的工作原理:但只在THEN處理程序中。請參閱我的回答https://stackoverflow.com/a/44948690/887092 – Todd