如何处理有关承诺的错误 (HTML)

Applies to Windows and Windows Phone

有时可能难以了解如何处理在承诺的不同阶段发生的异常。在快速入门:使用 JavaScript 中的承诺中,我们说明了如何使用基本的 Windows JavaScript 库承诺并如何处理 then 函数中的错误。

在本主题中,我们说明了使用承诺时捕获和处理错误的多种方式。你无需实现下列所有种类的错误处理,但是你应该选取最适合你的应用的错误处理类型。

先决条件

  • 本主题中的代码基于在快速入门:使用 JavaScript 中的承诺中创建的应用,因此,如果你想要继续学习,应该首先创建该应用。 请注意,仅当你使用 "ui-dark.css" 样式表时,下面提到的颜色才会与描述一致。

说明

步骤 1: 启用 JavaScript 首次机会异常

如果你启用首次机会异常,则无需执行其他任何异常处理操作便能够查看这些异常。在 Visual Studio 中的“调试”按钮上选择“异常”,然后在“异常”对话框中确保将“JavaScript 运行时异常”选择为“引发”。执行该操作之后,在调试模式下运行该应用。引发异常后,你会看到一个显示错误的消息框。只有当应用在调试程序中运行时,你才会看到此类对话框,因此用户不会看到这些异常。

步骤 2: 在 then 或 done 函数中添加错误处理程序

当你使用承诺时,应该添加一个 thendone 函数来明确该处理承诺的完成值(即在没有错误的情况下由承诺返回的值)和错误值。thendone 都采用三个函数(completederrorprogress)作为可选参数。使用 completed 函数在承诺履行之后执行更新,使用 error 函数处理错误,使用 progress 函数来显示或记录承诺的进度。

thendone 之间存在一些区别:

  • then 函数返回一个承诺,但 done 不返回值。你可以将 then 函数用作链 (myPromise().then().then().then()) 内的中间函数,但 done 必须是最后一个函数。

  • then 函数中未处理的异常作为承诺状态的一部分被无提示捕捉,但是,done 函数中的未处理异常被引发。这两个函数都可以处理已作为承诺状态一部分传递给它们的异常。

让我们看一下在 thendone 函数中处理错误的几种方式。在以下示例中,我们将建立由两个 then 函数组成的链,其中第一个 then 将错误传递给第二个。

  1. 在 TestPromise 项目中,添加另一个 DIV 元素并将其 ID 设为“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 函数中的错误函数。因此,第一个 DIV 应该是红色,第二个 DIV 应该是黑色。

在以下示例中,我们将从第二个 then 函数中删除 error 函数,并且添加一个不具有错误处理程序的 done 函数。

  1. 在 TestPromise 项目中,如果你尚未添加带有元素“div2”的第二个 DIV 元素,则现在应当添加。

  2. 修改更改处理程序,以从第二个 then 中删除错误函数,并添加一个将第二个 DIV 变为蓝色的 done 函数。更改处理程序代码应如下所示:

    
    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 处理程序

每当在承诺中捕捉到运行时错误时,都会发生 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;
        }
    
    
    

    错误事件提供常规错误信息(如异常)、发生错误的承诺以及承诺的当前状态(始终为 error)。但是,它可能未提供正常处理该错误所需的全部信息。但是,它仍然可以提供与你在代码中的其他位置未明确处理的错误相关的有用信息。

相关主题

使用 JavaScript 异步编程

 

 

显示:
© 2014 Microsoft