一、Promise 是什么
Promise 是 ES6 提供的用于处理异步操作的对象。
它有三种状态:
scss
pending (进行中)
fulfilled (成功)
rejected (失败)
基本写法:
typescript
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功")
}, 1000)
})
promise
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
特点:
- 通过
.then()处理成功 - 通过
.catch()处理错误 - 可以 链式调用
二、async / await 是什么
async/await 是 ES2017 提出的异步写法,是基于 Promise 的语法糖。
特点:
async声明函数为异步函数await等待 Promise 返回结果- 写起来像同步代码
例子:
javascript
async function getData() {
const res = await fetch("/api/data")
const data = await res.json()
console.log(data)
}
三、核心区别
| 对比点 | Promise | async/await |
|---|---|---|
| 写法 | 链式调用 | 同步风格 |
| 可读性 | 一般 | 更好 |
| 错误处理 | .catch() |
try...catch |
| 调试 | 不太友好 | 更像同步代码 |
| 本质 | 原生异步对象 | Promise 的语法糖 |
四、代码对比
Promise 写法
javascript
function getUser() {
return fetch("/user")
.then(res => res.json())
.then(data => {
console.log(data)
return fetch("/order")
})
.then(res => res.json())
.then(order => {
console.log(order)
})
.catch(err => {
console.log(err)
})
}
问题:
.then 链式调用太多
代码可读性差
async/await 写法
javascript
async function getUser() {
try {
const res = await fetch("/user")
const user = await res.json()
const res2 = await fetch("/order")
const order = await res2.json()
console.log(user, order)
} catch (err) {
console.log(err)
}
}
优点:
逻辑清晰
更像同步代码
更容易维护
五、async/await 的本质
其实:
csharp
async function test() {
return 1
}
等价于:
javascript
function test() {
return Promise.resolve(1)
}
所以:
javascript
async函数一定返回Promise
六、await 的作用
await 只能等待 Promise 对象。
例如:
csharp
const data = await fetch("/api")
等价于:
scss
fetch("/api").then(res => ...)
七、async/await 的限制
1 必须在 async 函数里
错误写法:
csharp
const data = await fetch("/api")
正确:
csharp
async function getData() {
const data = await fetch("/api")
}
2 默认是串行执行
csharp
const a = await getA()
const b = await getB()
执行顺序:
getA → 完成 → getB
有时候会变慢。
八、并发优化(重要)
如果两个请求 互不依赖:
错误写法:
csharp
const a = await getA()
const b = await getB()
优化写法:
scss
const [a, b] = await Promise.all([
getA(),
getB()
])
这样会 并发执行。
九、什么时候用 Promise?
适合:
- 并发请求
- 多个异步任务组合
Promise.allPromise.race
例如:
scss
Promise.all([api1(), api2(), api3()])
十、什么时候用 async/await?
适合:
- 顺序执行
- 复杂逻辑
- try/catch 错误处理
- 提高代码可读性
例如:
csharp
async function init() {
const user = await getUser()
const order = await getOrder(user.id)
}
十一、面试标准回答
可以这样说:
Promise 是 ES6 提供的用于处理异步操作的对象,通过 then 和 catch 进行链式调用。
async/await 是 ES2017 提供的语法,是 Promise 的语法糖,可以让异步代码写起来像同步代码,提高可读性。
async 函数会返回一个 Promise,await 用来等待 Promise 的结果。
在实际开发中,如果是复杂逻辑或者顺序执行,一般使用 async/await;如果是多个异步任务并发执行,通常配合 Promise.all 使用。
十二、再给你一个高级面试点(很多人不会)
很多人不知道:
csharp
await 123
也是合法的。
因为 JS 会自动变成:
javascript
await Promise.resolve(123)
最后总结
一句话记住:
javascript
Promise → 异步机制
async/await → Promise 的更优雅写法