记录一下,关于前端控制并发的思路

看了前端很多文章我感觉并发不应该只是控制几个接口去发送,应该考虑到每个接口完成的时间是不同的,所以今天我试着写了一个如果并发中接口完成了请求就继续发送其他接口的js ,简单测试了一下感觉没问题,还请各位提个建议

 

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
 
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js"></script>
 
 
    <script>
        const endpoints = [
            () =>
                $.ajax({
                    url: "https://jsonplaceholder.typicode.com/todos/1",
                    method: "GET",
                    dataType: "json",
                }),
            () =>
 
                $.ajax({
                    url: "https://jsonplaceholder.typicode.com/todos",
                    method: "GET",
                    dataType: "json",
 
                }),
            () =>
                $.ajax({
                    url: "https://jsonplaceholder.typicode.com/photos",
                    method: "GET",
                    dataType: "json",
                }),
 
            () =>
                $.ajax({
                    url: "https://dog.ceo/api/breeds/image/random111",
                    method: "GET",
                    dataType: "json",
                }),
 
            () =>
                $.ajax({
                    url: "https://jsonplaceholder.typicode.com/todos/4",
                    method: "GET",
                    dataType: "json",
                }),
            () =>
                $.ajax({
                    url: "https://jsonplaceholder.typicode.com/todos/5",
                    method: "GET",
                    dataType: "json",
                }),
        ];
 
 
 
        function parallelLimit(taskFns, limit) {
 
            const length = taskFns.length;
            // 1) 空数组快速返回
            if (length === 0) return Promise.resolve([]);
            // 2) 并发数校验
            if (!Number.isInteger(limit) || limit < 1) {
                return Promise.reject(new Error("并发数必须为正整数"));
            }
            //3)  判断当前执行结果会有多少个
            const results = new Array(length);
            let completed = 0; //记录执行了多少次
            let nextIndex = 0; //记录下一次执行的索引
            return new Promise((resolve, reject) => {
                // 创建runNext函数
                function runNext() {
                    // 如果下一次执行的索引大于等于数组长度,返回
                    if (nextIndex >= length) return;
                    // 获取当前执行的索引
                    const current = nextIndex++;
                    Promise.resolve()
                        //  开始执行任务
                        .then(() => taskFns[current]())
                        // 成功后走这里
                        .then((res) => {
                            results[current] = { status: "成功", res };
                            completed++;
                        })
                        //失败后走这里
                        .catch((error) => {
                            results[current] = { status: "失败", error };
                            completed++;
                        })
                        // 无论成功还是失败,都会走这里
                        .finally(() => {
                            if (completed >= length) {
                                resolve(results);
                            } else {
                                runNext();
                            }
                        });
                }
 
                //  判断一下limit 是否大于length
 
                const starters = Math.min(limit, length);
 
                for (let i = 0; i < starters; i++) runNext();
 
            });
 
        }
 
 
 
        function main() {
            const concurrency = 2;
            console.log("开始请求, 并发数 =", concurrency);
            parallelLimit(endpoints, concurrency).then((results) => {
                console.log("全部完成, 结果如下:");
                console.log(results);
            });
        }
 
 
 
        main();
 
 
    </script>
</body>
 
</html>

 

posted @ 2025-10-31 18:30  了了214  阅读(2)  评论(0)    收藏  举报