JavaScript 中 async 和 await 的使用

asyncawait 是 ES2017 引入的异步编程语法糖,它们基于 Promise,但让异步代码看起来更像同步代码,提高了可读性。

基本用法

1. async 函数

async 关键字用于声明一个异步函数:

async function myFunction() {
  return "Hello";
}

async 函数总是返回一个 Promise:

  • 如果返回值是非 Promise,会自动包装成 resolved Promise
  • 如果返回的是 Promise,则直接返回该 Promise

2. await 表达式

await 只能在 async 函数内部使用,它会暂停 async 函数的执行,等待 Promise 完成:

async function fetchData() {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  return data;
}

错误处理

1. try/catch

async function getUser() {
  try {
    const response = await fetch('https://api.example.com/user');
    const user = await response.json();
    return user;
  } catch (error) {
    console.error('获取用户失败:', error);
    throw error; // 可以选择重新抛出错误
  }
}

2. 直接处理 Promise 的 catch

async function getUser() {
  const response = await fetch('https://api.example.com/user').catch(error => {
    console.error('请求失败:', error);
    throw error;
  });
  // ...
}

实际应用示例

1. 顺序执行多个异步操作

async function processData() {
  const user = await getUser();
  const posts = await getPosts(user.id);
  const comments = await getComments(posts[0].id);
  return { user, posts, comments };
}

2. 并行执行多个异步操作

async function getDashboardData() {
  const [user, posts, notifications] = await Promise.all([
    getUser(),
    getPosts(),
    getNotifications()
  ]);
  return { user, posts, notifications };
}

3. 在循环中使用 await

async function processItems(items) {
  for (const item of items) {
    await processItem(item); // 顺序处理每个项目
  }
  
  // 或者并行处理
  await Promise.all(items.map(item => processItem(item)));
}

注意事项

  1. 顶层 await:在现代 JavaScript 中(ES2022+),可以在模块的顶层使用 await

    const data = await fetchData();
    console.log(data);
    
  2. 性能考虑:不必要的顺序 await 会影响性能,能并行的操作应该使用 Promise.all

  3. 浏览器兼容性:async/await 在现代浏览器中都支持,但在旧环境中需要 Babel 转译

  4. 不要滥用:不是所有函数都需要标记为 async,只有包含 await 或明确返回 Promise 的函数才需要

async/await 让异步代码更易于编写和维护,是处理 JavaScript 异步操作的首选方式。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐