HLJ 发布于
2025-06-11 11:06:02
2阅读

JavaScript async/await 详解与使用

JavaScript async/await 详解

async/await 是 ES2017 (ES8) 引入的处理异步操作的语法糖,它基于 Promise,但让异步代码看起来和同步代码一样,极大地提高了代码的可读性和可维护性。

基本概念

async 函数

  • 在函数声明前加上 async 关键字,表示该函数是异步的
  • async 函数总是返回一个 Promise 对象
    • 如果返回值不是 Promise,会自动包装成 resolved 状态的 Promise
    • 如果抛出异常,会返回 rejected 状态的 Promise
async function foo() {
  return 'Hello';
}
// 等价于
function foo() {
  return Promise.resolve('Hello');
}

await 表达式

  • await 只能在 async 函数内部使用
  • await 会暂停 async 函数的执行,等待 Promise 完成
    • 如果 Promise 被 resolve,await 会返回 resolve 的值
    • 如果 Promise 被 reject,会抛出异常(可以用 try/catch 捕获)
async function bar() {
  const result = await somePromise;
  console.log(result);
}

使用示例

基本用法

function fetchData() {
  return new Promise(resolve => {
    setTimeout(() => resolve('Data loaded'), 1000);
  });
}

async function getData() {
  console.log('Fetching data...');
  const data = await fetchData();
  console.log('Data:', data);
  return data;
}

getData().then(data => console.log('Final:', data));

错误处理

async function fetchWithError() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error fetching data:', error);
    throw error; // 可以选择重新抛出错误
  }
}

并行执行

async function parallel() {
  const [result1, result2] = await Promise.all([
    fetch(url1),
    fetch(url2)
  ]);
  // 处理结果...
}

注意事项

  1. 不要滥用 await:不必要的 await 会导致性能下降

    // 不好 - 两个请求会顺序执行
    async function sequential() {
      const a = await fetchA();
      const b = await fetchB();
      return a + b;
    }
    
    // 好 - 两个请求并行执行
    async function parallel() {
      const [a, b] = await Promise.all([fetchA(), fetchB()]);
      return a + b;
    }
    
  2. 顶层 await:在 ES2022 中,可以在模块顶层使用 await

    // 模块中
    const data = await fetchData();
    export default data;
    
  3. 循环中的 await:注意 forEach 和 map 中的 await 行为

    // 这样不会按预期工作
    items.forEach(async item => {
      await processItem(item);
    });
    
    // 应该使用 for...of
    for (const item of items) {
      await processItem(item);
    }
    
    // 或者并行处理
    await Promise.all(items.map(item => processItem(item)));
    

与传统 Promise 对比

// Promise 方式
function getUserAndPosts(userId) {
  return fetchUser(userId)
    .then(user => fetchPosts(user.id))
    .then(posts => {
      return { user, posts };
    })
    .catch(error => {
      console.error('Error:', error);
    });
}

// async/await 方式
async function getUserAndPosts(userId) {
  try {
    const user = await fetchUser(userId);
    const posts = await fetchPosts(user.id);
    return { user, posts };
  } catch (error) {
    console.error('Error:', error);
  }
}

实际应用场景

  1. API 调用:处理网络请求
  2. 文件操作:Node.js 中的 fs.promises
  3. 数据库操作:ORM 或数据库客户端
  4. 定时器:与 setTimeout 等结合使用

async/await 让异步代码更易于编写和理解,是现代 JavaScript 开发中处理异步操作的首选方式。

当前文章内容为原创转载请注明出处:http://www.good1230.com/detail/2025-06-11/835.html
最后生成于 2025-06-13 20:53:49
此内容有帮助 ?
0