在定制网站开发中,它几乎是处理异步场景的首选(如接口请求、文件上传、本地存储读取等),以下从 核心定义、用法、原理、特性、实战场景 全方位详解:
async 和 await 必须 成对使用(await 不能单独存在),二者分工明确:
先看一个 Promise 链式调用的例子(定制网站中常见的「获取用户信息 + 拉取用户订单」):

用 async/await 改写后,代码直接「线性同步化」,可读性大幅提升:

async/await 本质是 Promise + 生成器(Generator) 的语法糖,底层没有新增异步机制,只是简化了 Promise 的使用:
- 当异步函数执行到
await 时,会 暂停当前函数的执行上下文,并将后续代码(await 之后的部分)包装成 Promise 的 then() 回调;
- 等待
await 后面的 Promise 状态改变(成功 / 失败);
- 若 Promise 成功,将结果作为
await 表达式的返回值,恢复函数执行;
- 若 Promise 失败,抛出错误,需用
try/catch 捕获,否则函数返回的 Promise 会变为 rejected。
⚠️ 关键提醒:await 只会 暂停当前异步函数,不会阻塞整个 JS 线程(JS 仍是单线程,异步函数暂停时,主线程会继续执行其他同步代码)。
await 后的 Promise 若 rejected,会直接抛出错误,必须通过以下方式处理,否则会导致代码中断:
- 局部捕获:用
try/catch 包裹单个 / 多个 await(推荐,颗粒度更细);
- 全局捕获:通过异步函数返回的 Promise 的
.catch() 捕获(适合统一处理所有错误)。
示例(定制网站「登录 + 存储用户信息」场景):
若多个异步操作 无依赖关系(如同时拉取「产品列表」和「分类列表」),直接用 await 逐个执行会变成「串行」,浪费时间:

正确做法:用 Promise.all() 实现并行执行(总耗时 = 最长的单个请求时间):

其他并行工具:
Promise.race():等待第一个完成的 Promise(无论成功 / 失败),适合「超时控制」;
Promise.allSettled():等待所有 Promise 完成(无论成功 / 失败),适合「需要获取所有结果(成功 / 失败)」的场景(如批量上传文件,统计成功 / 失败数量)。
若 await 后面不是 Promise,会自动包装成「已 resolved 的 Promise」,返回该值本身:

-
在非 async 函数中使用 await → 语法错误!

忽略 fetch 的 404/500 状态码 → fetch 仅在「网络错误」时 reject,HTTP 错误(4xx/5xx)仍会 resolve,需手动判断 res.ok:

-
滥用 await 导致串行阻塞 → 无依赖的异步操作必须用 Promise.all() 并行执行(参考「并行执行」部分)。
-
await 后面的代码不会立即执行 → await 会暂停函数,直到 Promise 完成,后续代码属于「异步回调」:

-
未捕获的 await 错误 → 会导致异步函数返回的 Promise 变为 rejected,若未用 .catch() 捕获,会触发全局 unhandledrejection 事件,严重时导致页面崩溃。



- 代码简洁:告别 Promise 链式调用的
.then() 嵌套,逻辑更清晰;
- 可读性高:异步代码像同步代码一样线性执行,降低理解成本;
- 错误处理友好:用
try/catch 统一捕获所有异步错误,比 Promise 的多个 .catch() 更直观;
- 调试方便:断点调试时,可按同步代码的逻辑逐步执行(无需跳转到
.then() 回调)。
在定制网站开发中,只要涉及异步操作(接口请求、文件处理、定时器等),async/await 几乎是最优选择,配合 Promise 工具函数(Promise.all() 等)可高效处理复杂异步场景。