async/await和Promise的区别?

一、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.all
  • Promise.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 的更优雅写法
相关推荐
程序员大阳5 小时前
副队长JavaScript教程(49)-主动抛出异常与错误类型
javascript·异常处理·error·throw·错误类型
hhhjhl6 小时前
Protobuf.js 跨端三方库仓颉适配全流程
javascript·网络·udp
康小汪6 小时前
AI 写 Vue 总写成同一个味道:给它装 Skills,装的不是知识是边界
前端·vue.js·人工智能·ai编程·最佳实践
智能运维指南6 小时前
研制过程“两张皮“怎么破:研制一体化支撑平台的定位、能力边界与落地前提
java·前端·人工智能·嘉为蓝鲸
白山编程大哥8 小时前
Java 后端如何优雅地把 List 集合返回给前端
java·前端·list
Flynt9 小时前
我把热榜那篇"禁用 axios"逐条实测了一遍:结论大体对,坑在它没讲的地方
前端·javascript·axios
Csvn9 小时前
bundle优化
前端
slongzhang_10 小时前
linux 递归删除源码文件|递归删除目录下 *.js,但排除 *.min.js
linux·开发语言·javascript
北冥有鱼10 小时前
发版后动态路由点击报 `Failed to fetch dynamically imported module`」问题上的完整排查与修复过程
前端·vue.js
静默回滚10 小时前
视频压到 25 MB 以内,码率要算、音轨要扣、余量要留
前端