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

在前端开发中,页面请求接口大规模并发可能会导致浏览器性能下降、服务器压力过大、接口响应超时等问题。以下是一些常见的解决方法:

1. 限制并发请求数量

通过自定义请求队列,控制同时发起的请求数量,避免过多请求同时发出。

示例代码

javascript 复制代码
class RequestQueue {
    constructor(maxConcurrency) {
        this.maxConcurrency = maxConcurrency;
        this.currentConcurrency = 0;
        this.queue = [];
    }

    addRequest(request) {
        return new Promise((resolve, reject) => {
            const task = () => {
                this.currentConcurrency++;
                request()
                   .then((result) => {
                        resolve(result);
                    })
                   .catch((error) => {
                        reject(error);
                    })
                   .finally(() => {
                        this.currentConcurrency--;
                        if (this.queue.length > 0) {
                            const nextTask = this.queue.shift();
                            nextTask();
                        }
                    });
            };

            if (this.currentConcurrency < this.maxConcurrency) {
                task();
            } else {
                this.queue.push(task);
            }
        });
    }
}

// 使用示例
const queue = new RequestQueue(3); // 最大并发数为 3

function fetchData(id) {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(`Fetched data for id ${id}`);
            resolve(id);
        }, 1000);
    });
}

const requests = Array.from({ length: 10 }, (_, i) => () => fetchData(i));

requests.forEach((request) => {
    queue.addRequest(request).then((result) => {
        console.log(`Result: ${result}`);
    });
});

2. 合并请求

将多个相关的请求合并为一个请求,减少请求次数。

示例场景

例如,在电商页面中,需要获取多个商品的信息,可以将这些商品的 ID 一次性传递给后端接口,后端返回这些商品的详细信息。

javascript 复制代码
// 假设我们有多个商品 ID
const productIds = [1, 2, 3, 4, 5];

// 合并请求
fetch(`/api/products?ids=${productIds.join(',')}`)
  .then((response) => response.json())
  .then((data) => {
        console.log(data);
    });

3. 节流与防抖

  • 节流(Throttle):在一定时间内,只执行一次请求。适用于需要频繁触发的请求,如滚动加载数据。
  • 防抖(Debounce):在一定时间内,只有最后一次触发的请求会被执行。适用于搜索框输入提示等场景。

节流示例代码

javascript 复制代码
function throttle(func, delay) {
    let timer = null;
    return function() {
        if (!timer) {
            func.apply(this, arguments);
            timer = setTimeout(() => {
                timer = null;
            }, delay);
        }
    };
}

// 使用示例
function fetchDataOnScroll() {
    console.log('Fetching data on scroll');
    // 发起请求
}

window.addEventListener('scroll', throttle(fetchDataOnScroll, 500));

防抖示例代码

javascript 复制代码
function debounce(func, delay) {
    let timer = null;
    return function() {
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(this, arguments);
        }, delay);
    };
}

// 使用示例
function searchData(query) {
    console.log(`Searching for ${query}`);
    // 发起搜索请求
}

const input = document.getElementById('search-input');
input.addEventListener('input', debounce((e) => {
    searchData(e.target.value);
}, 300));

4. 缓存机制

对于一些不经常变化的数据,可以使用缓存机制,避免重复请求。

示例代码

javascript 复制代码
const cache = {};

function fetchDataWithCache(url) {
    if (cache[url]) {
        return Promise.resolve(cache[url]);
    }

    return fetch(url)
      .then((response) => response.json())
      .then((data) => {
            cache[url] = data;
            return data;
        });
}

// 使用示例
fetchDataWithCache('/api/data')
  .then((data) => {
        console.log(data);
    });

5. 分批次请求

将大量请求分成多个批次,依次发送请求,避免一次性发送过多请求。

示例代码

javascript 复制代码
const requests = Array.from({ length: 20 }, (_, i) => () => fetch(`/api/data/${i}`));
const batchSize = 5;

function sendRequestsInBatches() {
    const batch = requests.splice(0, batchSize);
    if (batch.length === 0) {
        return Promise.resolve();
    }

    const promises = batch.map((request) => request());
    return Promise.all(promises).then(() => sendRequestsInBatches());
}

sendRequestsInBatches().then(() => {
    console.log('All requests completed');
});
相关推荐
阿华的代码王国几秒前
【Android】适配器与外部事件的交互
android·xml·java·前端·后端·交互
mit6.8243 分钟前
[AI React Web] 包与依赖管理 | `axios`库 | `framer-motion`库
前端·人工智能·react.js
老虎06277 分钟前
JavaWeb前端(HTML,CSS具体案例)
前端·css·html
Mintopia13 分钟前
一个月速成 AI 工程师:从代码小白到智能工匠的修炼手册
前端·javascript·aigc
Mintopia16 分钟前
Next.js 全栈:接收和处理请求
前端·javascript·next.js
袁煦丞1 小时前
2025.8.18实验室【代码跑酷指南】Jupyter Notebook程序员的魔法本:cpolar内网穿透实验室第622个成功挑战
前端·程序员·远程工作
Joker Zxc1 小时前
【前端基础】flex布局中使用`justify-content`后,最后一行的布局问题
前端·css
无奈何杨1 小时前
风控系统事件分析中心,关联关系、排行、时间分布
前端·后端
Moment1 小时前
nginx 如何配置防止慢速攻击 🤔🤔🤔
前端·后端·nginx