JavaScript 如何创建一个全局Promise拒绝处理程序
答应拒绝处理程序是JavaScript中处理异步代码中发生的错误的一个强大工具。在这篇文章中,我们将学习如何在JavaScript中建立一个全局Promise拒绝处理程序,以及它如何协助你的应用程序管理错误。你可以使用全局unhandledrejection事件来检测未处理的Promise拒绝,并采取必要的行动,比如将问题记录到错误跟踪服务中,或向用户显示通知。
用async-await进行错误处理提供了一种更容易理解、更简单的处理Promise拒绝的语法,但它要求你用try-catch块来包装每个异步函数。Async-await与全局Promise拒绝处理程序相结合,可以给你的应用程序一个强大而可靠的错误处理系统。
什么是Promise拒绝
JavaScript中的Promise是处理异步代码的一种方式,例如从服务器获取数据或等待用户的输入。一个Promise是一个对象,代表一个可能还没有的值。许诺有三种状态–
Pending - 初始状态,既不履行也不拒绝。
已履行 - 意味着操作成功完成。
拒绝 - 意味着操作失败。
当一个Promise被拒绝时,如果Promise上有一个拒绝处理程序,它将触发一个拒绝处理程序。这允许你处理错误并采取适当的行动。然而,如果Promise没有附加拒绝处理程序,那么这个错误就不会被注意到,并可能导致你的应用程序出现错误。
创建一个全局Promise拒绝处理程序
JavaScript提供了一个全局unhandledrejection事件,可以用来捕获未处理的拒绝Promise。当一个Promise被拒绝时,unhandledrejection事件会被触发,并且没有拒绝处理程序被附加到该Promise上。
例子
<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被拒绝并且没有拒绝处理程序被附加到该Promise时,该事件将被触发。传递给事件监听器的事件对象包含一个持有拒绝原因的原因属性。
被拒绝的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是一种可读性更强、更简洁的诺言处理语法。在使用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拒绝处理程序,但它应该谨慎使用,并与其他错误处理系统一起使用。