如何使用 Promise 處理錯誤 (HTML)

Applies to Windows and Windows Phone

有時我們很難知道如何處理 Promise 不同階段的例外狀況。在快速入門:在 JavaScript 中使用 Promise 中,我們示範了如何使用基本「適用於 JavaScript 的 Windows Library」的 Promise 以及如何處理 then 函式中的錯誤。

在這個主題中,我們會示範多種方法以協助尋找和處理使用 Promise 時發生的錯誤。您不需要實作所有類型的錯誤處理,但您應該挑選您的應用程式最適用的錯誤處理類型。

先決條件

  • 這個主題中的程式碼是根據快速入門:在 JavaScript 中使用 Promise 中建立的應用程式所改編的,如果您想沿用,請先建立應用程式。 請注意,只有使用 "ui-dark.css" 樣式表,下面提到的色彩才會以所述的方式出現。

指示

步驟 1: 開啟 JavaScript 第一個可能發生的例外狀況

如果開啟第一個可能發生的例外狀況,您將可以查看例外狀況,不需要做任何事來處理它們。在 Visual Studio 中,選取 [偵錯] 功能表的 [例外狀況],然後在 [例外狀況] 對話方塊中,確定選取的 [ JavaScript 執行階段例外狀況] 是 [擲回]。.這樣做之後,以偵錯模式執行應用程式。擲回例外狀況時,您會看到顯示錯誤訊息的訊息方塊。只有當應用程式以偵錯工具執行時,您才會看到此類的對話方塊,因此使用者將不會看到這些例外狀況。

步驟 2: 在 then 或 done 函式中新增錯誤處理常式

使用 Promise 時,您必須新增 thendone 函式以明確處理完成的 Promise 值 (也就是沒有錯誤時,由 Promise 傳回的值) 以及錯誤值。thendone 都使用 3 個函式 (completederror 以及 progress) 做為選用參數。在 Promise 完成之後,使用 completed 函式執行更新、使用 error 函式處理錯誤以及使用 progress 函式顯示或記錄 Promise 目前的進度。

thendone 之間有幾項差異:

  • then 函式會傳回 Promise,但 done 則不會傳回值。您可以使用 then 函式做為鏈結中的中繼函式 (myPromise().then().then().then()),但 done 必須是最後一個函式。

  • then 函式中未處理的例外狀況會以無訊息的方式擷取為 Promise 狀態的一部分,但會擲回 done 函式中未處理的例外狀況。兩種函式都可以處理已傳遞給它們做為 Promise 狀態之一部分的例外狀況。

讓我們試試幾種方法來處理 thendone 函式中的錯誤。在這個範例中,我們會設定由兩個 then 函式形成的鏈結,第一個 then 會將錯誤傳送至第二個 then。

  1. 在 TestPromise 專案中,新增第二個 DIV 元素並為它指定識別碼 div2:

    
    <div id="div2">Second</div>
    
    
  2. 在變更處理常式中,從 then 函式移除錯誤處理常式,然後取得第二個 DIV 元素:

    
    function changeHandler(e) {
        var input = e.target;
        var resDiv = document.getElementById("divResult");
        var twoDiv = document.getElementById("div2");
    
        WinJS.xhr({url: e.target.value}).then(function fulfilled (result) {
                if (result.status === 200) {
                    resDiv.style.backgroundColor = "lightGreen";
                    resDiv.innerText = "Success";
            });
    }
    
    
  3. 新增第二個 then 函式並在其中加入 fulfilled 函式。如此一來,結果成功時就會變更第二個 DIV 的色彩。將原始錯誤處理常式新增至該函式。

    
    function changeHandler(e) {
        var input = e.target;
        var resDiv = document.getElementById("divResult");
        var twoDiv = document.getElementById("div2");
    
        WinJS.xhr({ url: e.target.value })
            .then(function (result) {
                if (result.status === 200) {
                    resDiv.style.backgroundColor = "lightGreen";
                    resDiv.innerText = "Success";
                }
                return result;
            })
            .then(function (result) {
                if (result.status === 200) {
                    twoDiv.style.backgroundColor = "yellow";
                }
            },
            function (e) {
                resDiv.style.backgroundColor = "red";
    
                if (e.message != undefined) {  // If the URL is really malformed or blank.
                    resDiv.innerText = e.message;
                }
                else if (e.statusText != undefined) { // If an XmlHttpRequest is made.
                    resDiv.innerText = e.statusText;
                }
                else {
                    resDiv.innerText = "Error";
                }
            });
        }
    
    
    
  4. 在偵錯工具中執行這個程式碼時,請試著輸入一個無效的 URL。您會看到程式碼執行時會在第二個 then 函式時進入 error 函式。因此,第一個 DIV 應該是紅色,而第二個 DIV 應該是黑色。

在下列的範例中,我們會從第二個 then 函式移除 error 函式,然後新增一個沒有錯誤處理常式的 done 函式。

  1. 在 TestPromise 專案中,如果尚未新增內含 "div2" 元素第二個 DIV 元素,請立即新增。

  2. 修改變更處理常式,從第二個 then 移除錯誤函式,然後新增 done 函式,它會將第二個 DIV 變成藍色。變更處理常式程式碼看起來就像這樣:

    
    function changeHandler(e) {
        var input = e.target;
        var resDiv = document.getElementById("divResult");
        var twoDiv = document.getElementById("div2");
    
        WinJS.xhr({ url: e.target.value })
            .then(function (result) {
                if (result.status === 200) {
                    resDiv.style.backgroundColor = "lightGreen";
                    resDiv.innerText = "Success";
                }
                return result;
            })
            .then(function (result) {
                if (result.status === 200) {
                    twoDiv.style.backgroundColor = "yellow";
                }
            })
            .done(function (result) {
                if (result.status === 200) {
                    twoDiv.style.backgroundColor = "lightBlue";
            }
        });
    }
    
    
    
  3. 在偵錯工具中執行這個程式碼時,請試著輸入一個無效的 URL。您應該會看到顯示錯誤訊息的訊息方塊。第一個和第二個 DIV 應該是黑色,因為未執行 then 函式或 done 函式中的任何程式碼。

步驟 3: 新增 WinJS.Promise.onerror 處理常式

只要在 Promise 中攔截到執行階段錯誤,就會發生 onerror 事件。您可以使用錯誤處理常式在進行偵錯時設定中斷點,或提供一般錯誤處理功能,例如錯誤記錄。但是因為這是一般的錯誤處理機制,所以您得不到錯誤程式碼原文或造成錯誤之使用者輸入的詳細資訊。

下列是新增一般錯誤處理常式的方式:

  1. 在 TestPromise 專案中,從 changeHandler 程式碼移除 then 函式。產生的 changeHandler 函式看起來就像這樣:

    
    function changeHandler(e) {
        var input = e.target;
        var resDiv = document.getElementById("divResult");
    
        WinJS.xhr({url: e.target.value});
    }
    
    
    
  2. 建立一般錯誤處理函式並訂閱 app.activated 事件處理常式中的 onerror 事件:

    
    app.activatedHandler = function (args) {
        var input = document.getElementById("inUrl");
        input.addEventListener("change", changeHandler);
        WinJS.Promise.onerror = errorHandler
    }
    function errorhandler(event) {
            var ex = event.detail.exception;
            var promise = event.detail.promise;
        }
    
    
    

    這個錯誤事件提供一般錯誤資訊,例如例外狀況、發生例外狀況的 Promise 以及 Promise 目前的狀態 (應該永遠是 error)。雖然它可能不會提供您順利處理錯誤所需的所有資訊。但它仍可提供關於程式碼中不需明確處理的錯誤資訊。

相關主題

JavaScript 的非同步程式設計

 

 

顯示:
© 2014 Microsoft