前端并发请求太多?教你几招轻松搞定!

前言

在前端开发中,处理大量请求时,如何控制并发请求数量是一个关键问题。

过多的并发请求可能导致服务器过载、用户体验下降,甚至引发性能瓶颈。

本文将介绍几种前端控制并发请求的方法,帮助你优化性能与用户体验。

一、为什么需要控制并发请求?

当前端应用需要同时发送大量请求时,如果不加以控制,可能会导致以下问题:

    1. 服务器过载:大量的并发请求可能导致服务器资源耗尽,影响服务器的响应速度,甚至导致服务器崩溃。
    1. 用户体验下降:过多的请求可能导致页面卡顿、加载缓慢,影响用户的操作体验。
    1. 资源浪费:未加控制的并发请求可能导致网络资源浪费,增加服务器的负担。

二、前端控制并发请求的方法

1. 使用队列控制并发请求

通过使用队列来管理请求,可以有效地控制并发请求数量。当请求数量超过设定的最大并发数时,多余的请求将被放入队列中等待执行。

示例代码

ini 复制代码
const MAX_CONCURRENT_REQUESTS = 5; // 最大并发请求数
let activeRequests = 0; // 当前活动请求数
const requestQueue = []; // 请求队列

function makeRequest(url) {
  return new Promise((resolve, reject) => {
    const request = () => {
      if (activeRequests < MAX_CONCURRENT_REQUESTS) {
        activeRequests++;
        fetch(url)
          .then(response => response.json())
          .then(data => {
            activeRequests--;
            resolve(data);
            if (requestQueue.length > 0) {
              requestQueue.shift()();
            }
          })
          .catch(error => {
            activeRequests--;
            reject(error);
            if (requestQueue.length > 0) {
              requestQueue.shift()();
            }
          });
      } else {
        requestQueue.push(request);
      }
    };
    request();
  });
}

在这个示例中,我们使用了一个队列来管理请求。当活动请求数小于最大并发数时,直接发起请求;否则,将请求加入队列[^44^]。

2. 使用 Promise 控制并发请求

通过使用 Promise.allPromise.race,可以实现对并发请求的控制。这种方法可以在任何时刻都保持最大数量的并发请求,而不需要等待整个批次完成。

示例代码

ini 复制代码
const MAX_CONCURRENT_REQUESTS = 5; // 最大并发请求数
const urls = []; // 请求地址数组

function concurrencyRequest(urls, maxNum) {
  return new Promise((resolve) => {
    if (urls.length === 0) {
      resolve([]);
      return;
    }
    const results = [];
    let index = 0; // 下一个请求的下标
    let count = 0; // 当前请求完成的数量

    // 发送请求
    async function request() {
      if (index === urls.length) return;
      const i = index; // 保存序号,使 result 和 urls 相对应
      const url = urls[index];
      index++;
      console.log(url);
      try {
        const resp = await fetch(url);
        // resp 加入到 results
        results[i] = resp;
      } catch (err) {
        // err 加入到 results
        results[i] = err;
      } finally {
        count++;
        // 判断是否所有的请求都已完成
        if (count === urls.length) {
          console.log('完成了');
          resolve(results);
        }
        request();
      }
    }

    // maxNum 和 urls.length 取最小进行调用
    const times = Math.min(maxNum, urls.length);
    for (let i = 0; i < times; i++) {
      request();
    }
  });
}

在这个示例中,我们通过递归调用 request 函数来控制并发请求的数量。每次最多发送 maxNum 个请求,当一个请求完成时,再从队列中取出下一个请求执行[^42^]。

3. 使用 axios 拦截器控制并发请求

通过使用 axios 的请求拦截器和响应拦截器,可以实现对并发请求的控制。这种方法可以在请求发送前和响应接收后进行拦截,从而控制并发请求数量。

示例代码

javascript 复制代码
import axios from 'axios';

const requestQueue = []; // 请求队列
const maxConcurrent = 3; // 最大并发请求数
let concurrentRequests = 0; // 当前并发请求数

// 请求拦截设置
axios.interceptors.request.use(
  (config) => {
    if (concurrentRequests < maxConcurrent) {
      concurrentRequests++;
      return config;
    } else {
      return new Promise((resolve) => {
        requestQueue.push({ config, resolve });
      });
    }
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截设置
axios.interceptors.response.use(
  (response) => {
    concurrentRequests--;
    if (requestQueue.length > 0) {
      const { config, resolve } = requestQueue.shift();
      concurrentRequests++;
      resolve(config);
    }
    return response.data;
  },
  (error) => {
    concurrentRequests--;
    return Promise.reject(error);
  }
);

在这个示例中,我们使用 axios 的拦截器来控制并发请求。当当前并发请求数小于最大并发数时,直接发送请求;否则,将请求加入队列[^43^]。

三、总结

前端控制并发请求的方法有多种,可以根据实际需求选择合适的方法。常见的方法包括:

    1. 使用队列控制并发请求:通过队列管理请求,控制并发请求数量。
    1. 使用 Promise 控制并发请求 :通过 Promise.allPromise.race 实现并发控制。
    1. 使用 axios 拦截器控制并发请求:通过 axios 的请求拦截器和响应拦截器实现并发控制。

无论选择哪种方法,关键在于合理控制并发请求数量,避免服务器过载,提升用户体验。希望这些方法能帮助你在前端开发中更好地处理并发请求问题。

相关推荐
Moment1 小时前
从方案到原理,带你从零到一实现一个 前端白屏 检测的 SDK ☺️☺️☺️
前端·javascript·面试
鱼樱前端1 小时前
Vue3 + TypeScript 整合 MeScroll.js 组件
前端·vue.js
拉不动的猪2 小时前
刷刷题29
前端·vue.js·面试
野生的程序媛2 小时前
重生之我在学Vue--第5天 Vue 3 路由管理(Vue Router)
前端·javascript·vue.js
codingandsleeping2 小时前
前端工程化之模块化
前端·javascript
CodeCraft Studio2 小时前
报表控件stimulsoft操作:使用 Angular 应用程序的报告查看器组件
前端·javascript·angular.js
阿丽塔~3 小时前
面试题之vue和react的异同
前端·vue.js·react.js·面试
烛阴3 小时前
JavaScript 性能提升秘籍:WeakMap 和 WeakSet 你用对了吗?
前端·javascript
yuren_xia4 小时前
eclipse创建maven web项目
前端·eclipse·maven
鱼樱前端4 小时前
Vue 2 与 Vue 3 语法区别完整对比
前端·javascript·vue.js