Promise简介
Promise 是一种用于处理异步操作的机制,它的目标是解决回调地狱问题。Promise 可以用于处理一系列由异步操作组成的任务,使得任务按照一定的顺序执行,并能够在完成时返回结果或者抛出错误。
一个 Promise 对象代表一个异步操作的最终完成结果,可以有三种状态:Pending(进行中)、Fulfilled(已成功)和Rejected(已失败)。当一个 Promise 对象的状态从 Pending 变为 Fulfilled 或者 Rejected 时,它的状态就不会再改变了。而且 Promise 对象可以链式调用,通过返回一个新的 Promise 对象,实现对异步操作的串联。
Promise 对象有两个重要的方法:then() 和 catch()。then() 方法用于注册当 Promise 对象状态变为 Fulfilled 时的回调函数,而 catch() 方法用于注册当 Promise 对象状态变为 Rejected 时的回调函数。
使用 Promise 的好处在于,它可以更加优雅地处理异步操作,让代码更加简洁易懂,并且避免了回调地狱问题。
try/catch简介
try/catch 是一种错误处理机制,用于捕获可能发生异常的代码块,避免程序因为错误而终止或崩溃。它的使用方法是通过在 try 代码块中包裹可能会引发错误的代码,然后通过 catch 代码块捕获并处理错误。
当 try 代码块中的代码发生错误时,程序会立即跳转到与之对应的 catch 代码块中执行,catch 代码块接收到一个 Error 对象作为参数,该对象包含了错误的详细信息,包括错误类型、错误消息、堆栈信息等。通过这些信息,我们可以对错误进行有效的处理和调试。
除了基本的 try/catch 机制,还有一些高级的用法,比如 try/finally 和 try-with-resources 等,它们可以用来释放资源和确保代码执行完成。
宏任务/微任务简介
任务被分为宏任务(macrotask)和微任务(microtask)两种类型。宏任务是指由浏览器在事件循环过程中排队执行的任务,如事件处理、setTimeout、setInterval 等。而微任务则是指在当前任务执行结束后立即执行的任务,如 Promise、MutationObserver 等。
宏任务和微任务的执行顺序也是有区别的。在事件循环过程中,每一次循环称为一个 tick。在每个 tick 中,会先执行所有微任务队列中的任务,直到所有微任务执行完毕,再执行宏任务队列中的一个任务。执行完这个宏任务后,再次执行所有微任务队列中的任务,这样循环往复,直到所有任务都执行完毕。
因此,Promise 的 then 和 catch 方法产生的回调函数都是微任务,而 setTimeout 和 setInterval 等产生的回调函数则是宏任务。对于同步代码,会在当前 tick 中直接执行,而不会产生任务。
理解宏任务和微任务的执行顺序对于处理异步代码非常重要,因为我们需要根据执行顺序来确定代码的执行结果。
为什么不能捕获异常
try/catch 只能捕获同步代码中的异常,而 Promise 是异步执行的,当 Promise 中的代码出错时,try/catch 已经执行完毕,此时 Promise 的错误已经逃离了 try/catch 的范围。
当一个 Promise 被 rejected 时,可以通过 catch 方法来捕获到这个错误,如下所示:
async function foo() {
try {
await somePromise;
} catch (err) {
console.log('Caught an error:', err);
}
}
另外,可以通过 Promise 的 catch 方法来捕获到未被处理的错误,如下所示:
somePromise.catch(err => console.log('Caught an error:', err));
在 async/await 中,如果使用 try/catch 语句,可以捕获到 async 函数中 await 异步函数执行出现的错误。
扩展阅读
www.yuque.com/shih_hsing/… 《实现一个简易版Promise》
juejin.cn/post/721354…
www.yuque.com/shih_hsing/… 《Event Loop》