Async/Await是什么_如何简化异步代码【教程】

7次阅读

async/await 是 javaScript 处理 promise 的标准化方式,不改变异步本质但降低回调嵌套与错误处理复杂度;async 函数自动包装返回值为 Promise,await 仅限 async 函数内使用且不阻塞线程

Async/Await是什么_如何简化异步代码【教程】

Async/await 不是新语法糖,而是 javascript 处理 Promise 的标准化方式;它本身不改变异步本质,但能显著降低回调嵌套和错误处理的复杂度。

async 函数必须显式返回 Promise

声明为 async 的函数会自动包装返回值为 Promise。即使你写 return 42,实际返回的是 Promise.resolve(42)。这意味着:

  • 不能靠 return 直接跳出异步流程(比如想提前终止请求)
  • 若函数内部抛出错误,会变成 rejected Promise,需用 try/catch.catch() 捕获
  • 如果忘记加 await 调用另一个 async 函数,你拿到的是一个 pending Promise,不是结果

await 只能在 async 函数内使用

await 是语法关键字,不是函数,也不能在顶层作用域或普通回调里用。常见误用场景包括:

  • foreach 回调中写 await → 实际上不会等待,因为 forEach 不支持异步迭代
  • setTimeout事件监听器中直接 await → 报错 SyntaxError: await is only valid in async function
  • 想在模块顶层 await 一个初始化操作 → 需改用 top-level await(仅 ES 模块且环境支持,如 node.js 14.8+ 或现代浏览器

await 会阻塞当前 async 函数,但不阻塞主线程

这是最容易误解的一点:await 暂停的是当前 async 函数的执行上下文,引擎会把控制权交还给事件循环。例如:

async function load() {   console.log('start');   await fetch('/api/data'); // 这里暂停,但 UI 仍可响应   console.log('done'); }

关键影响:

  • 多个 await 是串行的,想并发请用 Promise.all([p1, p2]) 包一层再 await
  • 没有超时机制,await apiCall() 可能永远卡住,生产环境应包裹 AbortController封装带 timeout 的 Promise
  • 调试时注意:断点停在 await 后一行,不代表前面请求已完成,只是 microtask 已入队

真正麻烦的从来不是写 async/await,而是搞清哪些地方该等、哪些不该等,以及怎么让错误流自然落到你写的 catch 块里 —— 尤其当混合使用 .then()await 时,拒绝路径容易意外丢失。

text=ZqhQzanResources