解锁JavaScript异步编程:Promise并发控制实战

简介: 解锁JavaScript异步编程:Promise并发控制实战

解锁JavaScript异步编程:Promise并发控制实战

在现代前端开发中,异步操作无处不在。JavaScript的Promise极大地简化了异步编程,但当我们需要同时处理大量异步任务时,直接使用Promise.all可能会带来性能问题甚至导致系统崩溃。

为什么需要并发控制?

想象一下,你有一个包含1000个URL的数组,如果同时发起所有请求,可能会导致:

  • 浏览器内存溢出
  • 服务器过载拒绝响应
  • 网络带宽被占满

实现Promise并发池

下面是一个简单而强大的并发控制函数:

class PromisePool {
   
  constructor(maxConcurrent) {
   
    this.maxConcurrent = maxConcurrent
    this.currentCount = 0
    this.queue = []
  }

  add(task) {
   
    return new Promise((resolve, reject) => {
   
      this.queue.push({
    task, resolve, reject })
      this._run()
    })
  }

  _run() {
   
    while (this.queue.length > 0 && this.currentCount < this.maxConcurrent) {
   
      const {
    task, resolve, reject } = this.queue.shift()
      this.currentCount++

      task()
        .then(resolve)
        .catch(reject)
        .finally(() => {
   
          this.currentCount--
          this._run()
        })
    }
  }
}

使用示例

// 创建最多同时处理3个请求的池
const pool = new PromisePool(3)

// 模拟异步任务
const tasks = Array.from({
    length: 10 }, (_, i) => 
  () => fetch(`/api/data/${
     i}`)
)

// 添加所有任务到池中
tasks.forEach(task => {
   
  pool.add(task).then(data => {
   
    console.log('任务完成:', data)
  })
})

总结

通过实现Promise并发控制,我们能够在保证系统稳定性的前提下,最大限度地利用可用资源。这种模式特别适用于文件上传、批量数据获取等场景,是每个前端开发者都应该掌握的实用技巧。

记住,好的并发控制就像交通信号灯,不是限制通行,而是确保所有车辆都能高效安全地到达目的地。

在现代前端开发中,异步操作无处不在。JavaScript的Promise极大地简化了异步编程,但当我们需要同时处理大量异步任务时,直接使用Promise.all可能会带来性能问题甚至导致系统崩溃。

为什么需要并发控制?

想象一下,你有一个包含1000个URL的数组,如果同时发起所有请求,可能会导致:

  • 浏览器内存溢出
  • 服务器过载拒绝响应
  • 网络带宽被占满

实现Promise并发池

下面是一个简单而强大的并发控制函数:

class PromisePool {
   
  constructor(maxConcurrent) {
   
    this.maxConcurrent = maxConcurrent
    this.currentCount = 0
    this.queue = []
  }

  add(task) {
   
    return new Promise((resolve, reject) => {
   
      this.queue.push({
    task, resolve, reject })
      this._run()
    })
  }

  _run() {
   
    while (this.queue.length > 0 && this.currentCount < this.maxConcurrent) {
   
      const {
    task, resolve, reject } = this.queue.shift()
      this.currentCount++

      task()
        .then(resolve)
        .catch(reject)
        .finally(() => {
   
          this.currentCount--
          this._run()
        })
    }
  }
}

使用示例

// 创建最多同时处理3个请求的池
const pool = new PromisePool(3)

// 模拟异步任务
const tasks = Array.from({
    length: 10 }, (_, i) => 
  () => fetch(`/api/data/${
     i}`)
)

// 添加所有任务到池中
tasks.forEach(task => {
   
  pool.add(task).then(data => {
   
    console.log('任务完成:', data)
  })
})

总结

通过实现Promise并发控制,我们能够在保证系统稳定性的前提下,最大限度地利用可用资源。这种模式特别适用于文件上传、批量数据获取等场景,是每个前端开发者都应该掌握的实用技巧。

记住,好的并发控制就像交通信号灯,不是限制通行,而是确保所有车辆都能高效安全地到达目的地。

目录
相关文章
|
18天前
|
前端开发 JavaScript
告别回调地狱:如何用Promise链优化异步代码
告别回调地狱:如何用Promise链优化异步代码
164 114
|
27天前
|
大数据 Python
Python列表推导式:优雅与效率的完美结合
Python列表推导式:优雅与效率的完美结合
220 114
|
18天前
|
自然语言处理 JavaScript 前端开发
理解JavaScript闭包:从入门到实战
理解JavaScript闭包:从入门到实战
213 118
|
17天前
|
JavaScript 前端开发 IDE
TypeScript:为你的JavaScript系上“安全带”
TypeScript:为你的JavaScript系上“安全带”
190 112
|
18天前
|
前端开发 UED
突破异步困境:巧用Promise.all()优化前端性能
突破异步困境:巧用Promise.all()优化前端性能
243 116
|
12天前
|
缓存 前端开发 JavaScript
告别useEffect:用新范式驯服React中的数据同步
告别useEffect:用新范式驯服React中的数据同步
161 121
|
5天前
|
安全 Java 编译器
告别样板代码:探索Java Record的简洁力量
告别样板代码:探索Java Record的简洁力量
152 114
|
12天前
|
弹性计算 Prometheus Cloud Native
从CPU到RPS:HPA避坑指南,让弹性伸缩不再“空转”
从CPU到RPS:HPA避坑指南,让弹性伸缩不再“空转”
164 115
|
9天前
|
Python
LBA-ECO ND-30 水化学,排除降雨,67 公里处,塔帕若斯国家森林
本数据集记录巴西塔帕若斯国家森林67公里处降雨排除实验期间(2000–2004年)水体化学变化,涵盖降水、穿透雨、渗滤液及土壤水的pH、电导率、离子浓度等指标,采样持续至2006年。旨在研究干旱对亚马逊森林生态系统的影响,包含5个CSV文件,支持地理空间查询与分析。
165 110
|
18天前
|
安全 Java API
优雅处理空值:Java Optional深度实践
优雅处理空值:Java Optional深度实践
227 115