Skip to content
WonvyWonvy

JavaScript 异步编程实战

一句话结论

合理使用 Promise 和 async/await 可以让异步代码更清晰、更易维护。

基础示例

Promise 链式调用

javascript
// 基础 Promise 使用
function fetchUserData(userId) {
  return fetch(`/api/users/${userId}`)
    .then(response => {
      if (!response.ok) {
        throw new Error('网络请求失败')
      }
      return response.json()
    })
    .then(data => {
      console.log('用户数据:', data)
      return data
    })
    .catch(error => {
      console.error('获取用户数据失败:', error)
      throw error
    })
}

async/await 语法

javascript
// 使用 async/await 简化代码
async function fetchUserDataAsync(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`)
    
    if (!response.ok) {
      throw new Error('网络请求失败')
    }
    
    const data = await response.json()
    console.log('用户数据:', data)
    return data
  } catch (error) {
    console.error('获取用户数据失败:', error)
    throw error
  }
}

并发处理

Promise.all - 并行执行

javascript
// 并行执行多个异步操作
async function fetchMultipleUsers(userIds) {
  try {
    const promises = userIds.map(id => fetchUserDataAsync(id))
    const users = await Promise.all(promises)
    return users
  } catch (error) {
    console.error('批量获取用户失败:', error)
    return []
  }
}

// 使用示例
const users = await fetchMultipleUsers([1, 2, 3, 4, 5])

Promise.allSettled - 等待所有完成

javascript
// 即使部分失败也继续执行
async function fetchUsersWithFallback(userIds) {
  const promises = userIds.map(id => fetchUserDataAsync(id))
  const results = await Promise.allSettled(promises)
  
  return results.map((result, index) => {
    if (result.status === 'fulfilled') {
      return { id: userIds[index], data: result.value, success: true }
    } else {
      return { id: userIds[index], error: result.reason, success: false }
    }
  })
}

错误处理模式

javascript
// 统一的错误处理包装器
function withErrorHandling(fn) {
  return async (...args) => {
    try {
      return await fn(...args)
    } catch (error) {
      console.error('操作失败:', error)
      // 可以在这里添加错误上报逻辑
      throw error
    }
  }
}

// 使用
const safeFetchUser = withErrorHandling(fetchUserDataAsync)

可复用的要点

  • 优先使用 async/await 而非 Promise 链
  • 使用 Promise.all 进行并行操作
  • 使用 Promise.allSettled 处理部分失败场景
  • 统一错误处理逻辑
  • 避免在 async 函数中忘记 await

参考链接