Skip to content

解决页面请求接口大规模并发问题

使用滑动窗口算法,来控制流量

场景

数据采集平台、低代码编辑平台,有序相对稳定发送到后端

方案

  • 请求队列
  • 防抖/节流
  • 分页加载 无限滚动

请求队列实现

js
class RequestQueue {
  constructor(maxConcurrent) {
    this.maxConcurrent = maxConcurrent // 最大并发请求数
    this.currentConcurrent = 0 // 当前并发请求数
    this.queue = []
  }

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

  processQueue() {
    if (this.queue.length > 0 && this.currentConcurrent < this.maxConcurrent) {
      const { request, resolve, reject } = this.queue.shift()
      this.currentConcurrent++
      request()
        .then(resolve)
        .catch(reject)
        .finally(() => {
          this.currentConcurrent--
          this.processQueue()
        })
    }
  }
}

// 请求函数
function fetchData(url) {
  return fetch(url).then((response) => response.json())
}

// 使用请求队列
const requestQueue = new RequestQueue(5)

const urls = [
  'https://api.example.com/data1',
  'https://api.example.com/data2',
  'https://api.example.com/data3',
  'https://api.example.com/data4',
  'https://api.example.com/data5',
  'https://api.example.com/data6',
  'https://api.example.com/data7',
  'https://api.example.com/data8'
]

const requests = urls.map((url) => () => fetchData(url))

Promise.all(requests.map((request) => requestQueue.add(request)))
  .then((results) => {
    console.log(results, '所用请求完成')
  })
  .catch((error) => {
    console.error(error, '请求失败')
  })

如何回答

  1. 在大数据量请求场景下,选用了请求队列,我主导封装了请求队列
  2. 防抖、节流 -> 在用户交互层面上解决减少请求处理
  3. 分页加载 滚动加载 -> 可视区绘制