如何在 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 次瀏覽

啟動您的 職業生涯

透過完成課程獲得認證

開始
廣告