如何在 JavaScript 中创建全局 Promise 拒绝处理程序?


Promise 拒绝处理程序是 JavaScript 中用于处理异步代码中发生的错误的强大工具。在本文中,我们将学习如何在 JavaScript 中构建全局 Promise 拒绝处理程序,以及它如何帮助您的应用程序管理错误。您可以使用全局的 unhandledrejection 事件检测未处理的 Promise 拒绝,并采取必要的措施,例如将问题记录到错误跟踪服务或向用户显示通知。

使用 async-await 进行错误处理提供了更易于理解和更简单的语法来处理 Promise 拒绝,但它需要您将每个异步函数包装在 try-catch 块中。结合使用 async-await 和全局 Promise 拒绝处理程序可以为您的应用程序提供强大且可靠的错误处理系统。

什么是 Promise 拒绝?

JavaScript 中的 Promise 是一种处理异步代码的方法,例如从服务器获取数据或等待用户的输入。Promise 是一个表示可能尚未可用的值的 对象。Promise 有三种状态 -

等待中 - 初始状态,既未完成也未拒绝。

已完成 - 表示操作已成功完成。

已拒绝 - 表示操作失败。

当 Promise 被拒绝时,如果 Promise 附加了拒绝处理程序,它将触发该处理程序。这使您可以处理错误并采取适当的措施。但是,如果 Promise 没有附加拒绝处理程序,则错误将被忽略,并可能导致应用程序中的错误。

创建全局 Promise 拒绝处理程序

JavaScript 提供了一个全局的 unhandledrejection 事件,可用于捕获未处理的 Promise 拒绝。当 Promise 被拒绝且没有附加拒绝处理程序时,将触发 unhandledrejection 事件。

示例

<html>
<body>
   <div id="error-message"></div>
   <script>
      window.addEventListener("unhandledrejection", event => {
         document.getElementById("error-message").innerHTML = event.reason;
      });
      
      // Create a new promise that intentionally rejects
      const myPromise = new Promise((resolve, reject) => {
         reject(new Error("Intentional error"));
      });

      // Use the promise
      myPromise.catch(error => {
         document.getElementById("error-message").innerHTML = error.message;
      });
   
      // Function to reject the promise when the button is clicked
      function rejectPromise() {
         myPromise.catch(() => {});
      }
   </script>
</body>
</html>

此代码将事件侦听器附加到全局未处理拒绝事件,当 Promise 被拒绝且没有附加拒绝处理程序时,将触发该事件。传递给事件侦听器的事件对象包含一个 reason 属性,该属性保存拒绝原因。

使用此事件还可以更集中地处理被拒绝的 Promise。例如,您可以使用它向用户显示消息、将问题记录到错误跟踪服务或执行其他必要的操作。在处理大型应用程序时,这可能非常有用,在大型应用程序中,跟踪所有 Promise 及其关联的拒绝处理程序可能很困难。

window.addEventListener("unhandledrejection", event => {
    logErrorToService(event.reason);
    displayErrorMessage(event.reason);
});

示例

我们可以按如下方式在代码中使用上述代码段 -

<html>
<body>
   <div id="error-log"></div>
   <div id="error-message"></div> 
   <script>
      window.addEventListener("unhandledrejection", event => {
         logErrorToService(event.reason);
         displayErrorMessage(event.reason);
      });
      function logErrorToService(error) {
         
         // Code to log error to a service
         var errorLog = document.getElementById("error-log");
         errorLog.innerHTML = error;
      }
      function displayErrorMessage(error) {
         
         // Code to display error message on screen
         var errorMessage = document.getElementById("error-message");
         errorMessage.innerHTML = error;
      }
      
      // Create a new promise that intentionally rejects
      const myPromise = new Promise((resolve, reject) => {
         reject(new Error("Intentional error"));
      });
      
      // Use the promise and handle the rejection
      myPromise.catch(error => {
         displayErrorMessage(error.message);
      });
   </script>
</body>
</html>

在此示例中,捕获了 unhandledrejection 事件,并将错误发送到两个不同的函数:一个函数将错误报告给错误跟踪服务,另一个函数向用户显示错误消息。

在实现此功能时,您应该谨慎,并注意不要干扰应用程序中已存在的任何其他错误处理机制,因为此全局事件侦听器将捕获页面上所有未处理的 Promise 拒绝。

使用 Async-Await 进行错误处理

Async-await 是用于处理 Promise 的更易读且更简洁的语法。使用 async-await 时,您可以使用标准的 try-catch 块来处理错误。

async function fetchData() {
     try {
         const response = await
        fetch('https://jsonplaceholder.typicode.com/posts/1');
         const data = await response.json();
         console.log(data);
     } catch (error) {
         console.error(error);
     }
}

示例

我们可以按如下方式在代码中使用上述代码段 -

<html>
<body>
   <script>
      async function fetchData() {
         try {
            const response = await
            fetch('https://jsonplaceholder.typicode.com/posts/1');
            const data = await response.json();
            var dataDisplay = document.getElementById("data-display");
            dataDisplay.innerHTML = JSON.stringify(data);
         } catch (error) {
            var errorDisplay = document.getElementById("error-display");
            errorDisplay.innerHTML = error;
         }
      }
   </script>
   <button onclick="fetchData()">Fetch Data</button>
   <div id="data-display"></div>
   <div id="error-display"></div>
</body>
</html>

在此示例中,使用 await 关键字,异步函数 fetchData 等待 fetch 方法返回的 Promise 解析。catch 块将捕获 try 块中发生的任何错误并将其记录到控制台。

虽然这种方法更易于访问和理解,但它需要您将每个异步函数包装在 try-catch 块中。在处理包含大量异步代码的大型系统时,这可能会变得很繁琐且容易出错。

但是,结合使用 async-await 和全局 Promise 拒绝处理程序可以提供强大的错误处理机制。通过使用全局 Promise 拒绝处理程序来捕获未处理的 Promise 拒绝,您可以确保处理应用程序中的所有错误,即使您忘记将异步函数包装在 try-catch 块中。

重要的是要记住,有效的错误处理对于提供更好的用户体验和快速修复错误至关重要。全局 Promise 拒绝处理程序是一个有价值的工具,可以帮助您做到这一点,但应谨慎使用,并与其他错误处理机制结合使用。

更新于:2023 年 3 月 2 日

906 次浏览

启动您的 职业生涯

通过完成课程获得认证

开始
广告

© . All rights reserved.