- Published on
异步编程
- Authors

- Name
- Li WenKang
- https://x.com/liwenkang_space
在 JavaScript 中,存在一些异步操作,需要等浏览器执行完成之后,再告诉主线程,我们再去做后续的操作 之前为了实现这一点,我们会用回调函数的方式,拿到异步的执行结果,并做后续处理
但如果我们在某一个回调函数中,又依赖其他回调函数带过来的参数,就会存在回调地狱(混乱的嵌套),且难以维护和控制状态,由此 es6 引入了 Promise 的概念。一个 Promise 本身只有三种状态,pending(待定),fulfilled(成功),rejected(失败),当状态从待定,变成成功或失败后,状态将固定不再发生变化。它支持链式调用,then 和 catch 方法总会返回一个新的 promise 对象,从而将嵌套的回调拉平,且可以将状态通过链式传递下去。
如果then中的回调函数:
- 返回了一个值(包括另一个Promise),那么新返回的Promise会以这个值作为成功状态的结果。
- 没有返回值,新返回的Promise会以undefined作为成功状态的结果。
- 抛出了错误,新返回的Promise则会变为失败状态。
而 Async 和 Await,则是Promise 的语法糖,通过它,我们可以使用同步的代码写法,实现异步的功能。一个函数被async关键字修饰后,它无论如何都会返回一个Promise对象。
- 如果函数内显式返回一个非Promise值,这个值会被自动包装成一个已解决的Promise;
- 如果函数抛出异常,则会返回一个被拒绝的Promise。
如何使用它?
new Promise((resolve, reject) => {
setTimeout(() => {
// 模拟一个异步接口请求
resolve(true)
}, 1000)
})
.then((data) => {
console.log(data)
})
.catch((error) => {
console.error(error)
})
const getData = async () => {
try {
const response = await fetch('https://www.api.com')
console.log('response', response)
} catch (e) {
console.error('e', e)
}
}
解决了什么问题? Promise 解决了回调地狱,便于管理状态。Async/Await 让异步处理可以跟同步一样,使代码逻辑更清晰
最佳实践有哪些?
- 无依赖的异步任务使用 Promise.all并行执行提升效率
- 手动处理接口超时,可以定义一个超时Promise(比如限定 30s 后,返回失败),使用 Promise.race([]),将实际接口请求,和超时 Promise 都放进去,让它们"竞速"
- 在使用 async/await 的时候,一定要用 try/catch 做错误处理
- Promise 链中必须使用 catch 做错误处理