实现网络请求并发限制的管理类 NetManager(concurrency),构造函数传入一个number,是并发的限制数,提供 request(url, da

772 阅读1分钟

代码实现

// 实现网络请求并发限制的管理类 NetManager(concurrency),构造函数传入一个number,是并发的限制数,提供 request(url, data) => Promise<res> 方法
// Const obj = new NetManager(5)
// obj.request(“/xxx/sss”, {a: 1})

// index.js
class NetManager {
    constructor(number) {
        if (!(typeof number === 'number' && !Number.isNaN(number))) {
            console.error(
                `NetManager params typeof number === '${typeof number}', value: ${number}`
            );
        }

        this.number = number;
        this.queues = [];
        this.caches = [];
    }

    trigger = () => {
        const hits = this.queues.filter((i) => i.isFetch === false);
        hits.forEach((item) => {
            item.isFetch = true;

            item.task()
                .then(item.resolve)
                .catch(item.reject)
                .finally(() => {
                    const deleteIndex = this.queues.findIndex(
                        (del) => del.key === item.key
                    );

                    if (deleteIndex !== -1) {
                        this.queues.splice(deleteIndex, 1);
                    }

                    if (this.caches.length > 0) {
                        this.queues.push(this.caches.shift());
                        this.trigger();
                    }
                });
        });
    };

    request = (...reset) => {
        return new Promise((resolve, reject) => {
            // 绑定一个函数并传参
            const task = window.fetch.bind(null, ...reset);

            // 生成一个key值,用于删除队列任务
            const key = Math.random();

            const newItem = {key, isFetch: false, task, resolve, reject};
            if (this.queues.length >= this.number || this.caches.length > 0) {
                this.caches.push(newItem);
            } else {
                this.queues.push(newItem);
                this.trigger();
            }
        });
    };
}
const JSON_PLACEHOLDER = 'https://jsonplaceholder.typicode.com/todos/';

const obj = new NetManager(2);

for (let i = 1; i <= 10; i++) {
    obj.request(`${JSON_PLACEHOLDER}${i}`, {credentials: 'include'})
        .then((res) => res.json())
        .then((result) => {
            console.log('result', result);
        });
}

index.html

<!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="./index.js"></script>
</body>
</html>

执行结果

浏览器中打开index.html