管理

(转载)20个JavaScript重点知识点(17)Async/Await

Posted on 2025-07-24 10:00  lzhdim  阅读(10031)  评论(0)    收藏  举报

Async/Await 是 ES2017 引入的语法糖,用于简化 Promise 的使用,让异步代码看起来像同步代码。它的核心原理是:

  • async:声明一个函数为异步函数

  • await:暂停代码执行,等待 Promise 结果

  •  

与传统 Promise 对比

// Promise 写法function fetchData() {  return fetch('url')    .then(response => response.json())    .catch(err => console.error(err));}
// Async/Await 写法async function fetchData() {  try {    const response = await fetch('url');    return response.json();  } catch (err) {    console.error(err);  }}

2. 基本语法规则

2.1 声明异步函数

使用 async 关键字修饰函数:

// 函数声明async function myAsyncFunc() { /* ... */ }
// 箭头函数const myAsyncFunc = async () => { /* ... */ };
// 对象方法const obj = {  async fetchData() { /* ... */ }};

2.2 使用 await

await 只能在 async 函数内部使用:

async function example() {  const result = await somePromise; // 等待 Promise 完成  console.log(result);}

2.3 返回值自动包装

异步函数始终返回 Promise:

async function foo() {  return 42; // 自动包装为 Promise.resolve(42)}
foo().then(result => console.log(result)); // 42

3. 错误处理

3.1 try/catch 捕获错误

async function fetchUser() {  try {    const response = await fetch('/api/user');    const data = await response.json();    return data;  } catch (error) {    console.error('请求失败:', error);    throw error; // 可选择继续抛出错误  }}

3.2 结合 .catch()

async function example() {  const data = await fetchData().catch(err => {    console.error('备用处理:', err);    return defaultValue;  });}

4. 并行执行技巧

4.1 并行执行多个异步操作

使用 Promise.all

async function fetchAll() {  const [users, posts] = await Promise.all([    fetch('/api/users'),    fetch('/api/posts')  ]);
  // 等待所有结果完成后再处理  const userData = await users.json();  const postData = await posts.json();
  return { userData, postData };}

4.2 按需执行

// 串行执行const result1 = await task1();const result2 = await task2(result1);
// 并行执行(无依赖关系时)const [r1, r2] = await Promise.all([task1(), task2()]);

5. 常见使用场景

5.1 网络请求

async function getUserPosts(userId) {  const user = await fetch(`/users/${userId}`);  const posts = await fetch(`/posts?userId=${userId}`);  return { user, posts };}

5.2 文件操作(Node.js)

const fs = require('fs').promises;
async function readFiles() {  const file1 = await fs.readFile('file1.txt', 'utf8');  const file2 = await fs.readFile('file2.txt', 'utf8');  return file1 + file2;}

5.3 定时器控制

function delay(ms) {  return new Promise(resolve => setTimeout(resolve, ms));}
async function countdown() {  console.log(3);  await delay(1000);  console.log(2);  await delay(1000);  console.log(1);}

6. 注意

6.1 避免阻塞陷阱

错误写法:

// 这会依次执行等待,导致总时间叠加const a = await task1(); // 等待 1sconst b = await task2(); // 再等待 1s → 总 2s
// 正确并行写法 → 总 1sconst [a, b] = await Promise.all([task1(), task2()]);

6.2 循环中的 await

// 依次执行(可能不符合预期)for (const url of urls) {  await fetch(url); // 每个请求串行执行}
// 并行执行所有请求const promises = urls.map(url => fetch(url));await Promise.all(promises);

6.3 顶级 await

在 ES2022+ 的模块中可使用:

// 模块顶层直接使用const data = await fetchData();export default data;

7. 总结

关键点说明
async 函数返回值 总是返回 Promise
await 作用范围 只能在 async 函数内部使用
错误处理优先级 优先使用 try/catch
并行执行优化 合理使用 Promise.all
避免过度串行化 注意循环中的 await 使用
浏览器兼容性 现代浏览器/Node.js 7.6+ 支持

  1. 优先使用 async/await 替代 Promise 链式调用

  2. 复杂的异步逻辑使用 Promise.all/Promise.race 优化

  3. 始终处理错误(要么 try/catch,要么 .catch()

  4. 在需要兼容旧环境时使用 Babel 转译

掌握 async/await 能让异步代码更易读、更易维护,是现代 JavaScript 开发的必备技能!

Copyright © 2000-2022 Lzhdim Technology Software All Rights Reserved