Skip to content

异步/高并发方案

概述

异步编程和高并发处理是现代前端开发的核心技能,涉及事件循环、Promise、async/await 等关键技术。

异步编程基础

1. 回调函数

javascript
function fetchData(callback) {
  setTimeout(() => {
    callback(null, 'data')
  }, 1000)
}

2. Promise

javascript
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('data')
    }, 1000)
  })
}

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error))

3. async/await

javascript
async function fetchData() {
  try {
    const data = await fetch('/api/data')
    return data.json()
  } catch (error) {
    console.error(error)
  }
}

并发控制

1. Promise.all()

并行执行多个 Promise,等待所有完成:

javascript
const results = await Promise.all([
  fetch('/api/1'),
  fetch('/api/2'),
  fetch('/api/3')
])

2. Promise.race()

返回最先完成的 Promise:

javascript
const result = await Promise.race([
  fetch('/api/fast'),
  timeout(5000)
])

3. Promise.allSettled()

等待所有 Promise 完成(无论成功或失败):

javascript
const results = await Promise.allSettled([
  fetch('/api/1'),
  fetch('/api/2')
])

4. 并发限制

javascript
class ConcurrencyQueue {
  constructor(limit) {
    this.limit = limit
    this.queue = []
    this.active = 0
  }

  async run(task) {
    if (this.active >= this.limit) {
      await new Promise(resolve => this.queue.push(resolve))
    }

    this.active++
    try {
      return await task()
    } finally {
      this.active--
      const next = this.queue.shift()
      if (next) next()
    }
  }
}

高并发场景

1. 批量请求处理

javascript
async function batchRequests(urls, batchSize = 5) {
  const results = []
  
  for (let i = 0; i < urls.length; i += batchSize) {
    const batch = urls.slice(i, i + batchSize)
    const batchResults = await Promise.all(
      batch.map(url => fetch(url))
    )
    results.push(...batchResults)
  }
  
  return results
}

2. 请求取消

javascript
const controller = new AbortController()

fetch('/api/data', {
  signal: controller.signal
})

// 取消请求
controller.abort()

3. 请求重试

javascript
async function fetchWithRetry(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await fetch(url)
    } catch (error) {
      if (i === retries - 1) throw error
      await new Promise(r => setTimeout(r, 1000 * i))
    }
  }
}

性能优化

1. 防抖和节流

javascript
// 防抖
function debounce(fn, delay) {
  let timer
  return function(...args) {
    clearTimeout(timer)
    timer = setTimeout(() => fn.apply(this, args), delay)
  }
}

// 节流
function throttle(fn, delay) {
  let last = 0
  return function(...args) {
    const now = Date.now()
    if (now - last >= delay) {
      last = now
      fn.apply(this, args)
    }
  }
}

2. 虚拟列表

javascript
function VirtualList({ items, itemHeight, containerHeight }) {
  const [scrollTop, setScrollTop] = useState(0)
  
  const startIndex = Math.floor(scrollTop / itemHeight)
  const endIndex = Math.min(
    startIndex + Math.ceil(containerHeight / itemHeight),
    items.length
  )
  
  return (
    <div onScroll={e => setScrollTop(e.target.scrollTop)}>
      {items.slice(startIndex, endIndex).map(item => (
        <div key={item.id}>{item.content}</div>
      ))}
    </div>
  )
}

最佳实践

1. 错误处理

  • 使用 try-catch 捕获异步错误
  • 实现全局错误处理
  • 记录错误日志

2. 超时控制

javascript
function timeout(promise, ms) {
  return Promise.race([
    promise,
    new Promise((_, reject) => 
      setTimeout(() => reject(new Error('Timeout')), ms)
    )
  ])
}

3. 资源清理

  • 取消未完成的请求
  • 清理定时器
  • 移除事件监听器

常见问题

如何处理并发竞态问题?

  • 使用请求标识符
  • 取消过期的请求
  • 使用最新结果

如何优化大量并发请求?

  • 实现请求队列
  • 控制并发数量
  • 使用缓存策略

相关资源

基于 VitePress 的本地知识库