目标

通过concurRequest(urls, maxNums)的形式发起并发请求,参数为url数组最大并发数量,返回值为Promise,成功结果为原url顺序的响应结果数组

代码实现

concurRequest.js

/**
 * 并发请求
 * @param {string[]} urls 待请求的 url 数组
 * @param {number} maxNum 最大并发数
 */

function concurRequest(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;
            const url = urls[index];
            index++;
            try {
                const resp = await fetch(url);
                // resp加入到 results
                results[i] = resp;
            } catch (err) {
                // err加入到 results
                results[i] = err;
            } finally {
                // 判断是否所有的请求都已完成
                count++;
                if (count === urls.length) {
                    // 所有请求完成,返回结果
                    resolve(results);
                }
                request();
            }
        }
        const times = Math.min(maxNum, urls.length);
        for (let i = 0; i < times; i++) {
            request();
        }
    });
}

test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>并发请求</title>
</head>
<body>
    <script src="./concurRequest.js"></script>
    <script>
        const urls = [];
        for(let i = 1; i <= 20; i++){
            urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
        }
        concurRequest(urls, 3).then((resps) => {
            console.log(resps);
        })
    </script>
</body>
</html>

可通过浏览器调试工具查看测试结果及请求过程。

效果展示

%E6%88%AA%E5%B1%8F2023-08-15%2015.42.10.png

>查看视频演示<


A Student on the way to full stack of Web3.