2.如何解决页面请求接口大规模并发问题

滑动窗口算法,专门来控制流量的

1. 背景

常见与数据采集平台、低代码平台,我们需要有序切文档地把数据发送到后端

2. 方案

2.1 封装请求队列

  • 一个队列设计到入队和出队,当我们有一大批的流量进来之后,因为我们只有一个通道,在这个队列中间,我们限制它的数量,比如说一次性只能发送四个请求,当这四个请求完成之后,或者某一个请求完成之后,再次放入请求
const queue=[]

queue.push()
queue.shift()
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)// 设定最大并发数为5

const urls=[
  'https://api.example.com/data1',
  'https://api.example.com/data1'
]

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

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

2.2 防抖节流

  • 防抖(debounce)
    • 你一直输入的时候,为了不让你抖动,只取你在间隔外最后一次
  • 节流(throttle)
    • 按照一个时间间隔,一直在执行间隔内第一次请求

2.3 分页加载

let currentPage=1
const pageSize=20
let isLoading=false

function loadMoreData(){
  if(isLoading) return
  isLoading=false
  fetch(`/api/items?page=${currentPage}&size=${pageSize}`)
    .then(response => response.json())
    .then(data=>{
      //处理数据更新页面
      const container=document.getElementById('item-container')
      data.items.forEach(item=>{
        const itemElement=document.createElement('div')
        itemElement.textContent=item.name
        container.appendChild(itemElement)
      })
      currentPage++
      isLoading=false
    })
}

// 监听滚动事件
window.addEventListener('scroll',()=>{
  if(window.innerHeight | window.screenY >=document.body.offsetHeight){
    loadMoreData()
  }
})

// 初始化加载
loadMoreData()

3. 落地

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