JavaScript请实现,最多允许同时发三个ajax请求,有100个请求要发送。

原题

版本一:
 

const pipRequest = (idsarr, callback) => {

    const start = Date.now();

    const len = idsarr.length;
    const result = []; // 结果集
    const ajaxMax = 3; // 最多允许同时执行的ajax次数
    let ajaxNum = 0; // 当前有多少ajax正在执行

    const ajax = (id) => new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`${id}的结果`);
        }, 500);
    })

    const main = (ids) => {
        console.log(`时间:${Date.now() - start}`);
        while (ajaxNum <= ajaxMax && ids.length > 0) { // 只要有位置就发请求
            ajaxNum++;
            const now = ids.shift() // 发了一个请求
            ajax(now).then(res => {
                result.push(res);
                main(ids);
            }).catch((_) => {
                ids.push(now); // 失败的请求重新加入队列
            }).finally(() => {
                ajaxNum--;
                (
                    result.length === len
                    && typeof callback === 'function'
                    && callback(result)
                );
            })

        }
    }
    main(idsarr);
}

pipRequest([...Array(100).keys()], function (res) {
    console.log(res);
})

版本二:
这个版本比较好理解,但是实现私有属性的#方法兼容性很差。


 

const ajax = (id) => new Promise((resolve, reject) => setTimeout(() => {
    resolve(`${id}结果`);
}, 500))
class Request {
    // 初始化数据
    constructor(arr = [], callback) {
        this.arr = arr;
        this.callback = this.#checkCallBackLegal(callback) && callback;
    }

    #result = [];
    #curIndex = 0;
    #maxNum = 3;
    #pool = new Set();

    // 启动函数,从arr的第0项开始启动
    async start() {
        await this.#addPool();
    }

    // 加入池子,如果池中满了或者超出则不放置
    #addPool = ()=>{
        if (this.#pool.size < this.#maxNum && this.arr.length > this.#curIndex) {
            const id = this.#send();
            this.#pool.add(id);
            this.#curIndex++;
            this.#addPool();
        }
    }

    // 移出池子
    #removePool = (id)=>{
        this.#pool.delete(id)
    }

    // 返回ajax,单个请求
    #send = ()=>{
        const id = this.#curIndex;
        ajax(this.arr[id]).then((res) => {
            this.#log(res);
            this.#result.push(res);
        }).then(res => {
            this.#removePool(id);
            this.#addPool();
            this.#doCallBack()
        });
        return id;
    }

    #log = (res)=>{
        console.log(`${res} has been resolved`);
    }

    #checkCallBackLegal = (callback)=>{
        return (callback && typeof callback === 'function');
    }

    #doCallBack = ()=>{
        if (this.arr.length === this.#result.length) {
            this.callback(this.#result);
        }
    }
}

const arr = [...Array(100).keys()];
new Request(arr, (res) => {
    console.log(res);
}).start();

版本三:
这个版本的私有成员兼容性比较好,但是这TM也太难看了,突然想说java真香,JavaScript就是个垃圾。
 

// 函数闭包化
const closure = (func) => {
    return (func)();
}
// ajax
const ajax = (id) => new Promise((resolve, reject) => setTimeout(() => {
    resolve(`${id}结果`);
}, 500))


var Request =() => {
    // 实现私有属性
    const result = Symbol();
    const curIndex = Symbol();
    const maxNum = Symbol();
    const pool = Symbol();
    const addPool = Symbol();
    const removePool = Symbol();
    const send = Symbol();
    const log = Symbol();
    const checkCallBackLegal = Symbol();
    const doCallBack = Symbol();

    class Request {
        constructor(arr = [], callback) {
            // 初始化数据
            this.arr = arr;
            this.callback = this[checkCallBackLegal](callback) && callback;
            // 初始化私有属性
            this[result] = [];
            this[curIndex] = 0;
            this[maxNum] = 3;
            this[pool] = new Set();
        }

        // 启动函数,从arr的第0项开始启动
        async start() {
            await this[addPool]();
        }

        // 加入池子,如果池中满了或者超出则不放置
        [addPool]() {
            if (this[pool].size < this[maxNum] && this.arr.length > this[curIndex]) {
                this[send]();
                this[pool].add(this[curIndex]);
                this[curIndex]++;
                this[addPool]();
            }
        }

        // 移出池子
        [removePool](id) {
            this[pool].delete(id)
        }

        // 返回ajax,单个请求
        [send]() {
            const id = this[curIndex];
            ajax(this.arr[id]).then((res) => {
                this[log](res);
                this[result].push(res);
            }).then((_) => {
                this[removePool](id);
                this[addPool]();
                this[doCallBack]();
            });
        }

        // 打印日志
        [log](res) {
            console.log(`${res} has been resolved`);
        }

        // 检查回调函数是否合法
        [checkCallBackLegal](callback) {
            return (callback && typeof callback === 'function');
        }

        // 执行回调函数
        [doCallBack]() {
            // 执行回调函数的时机判断,
            if (this.arr.length === this[result].length) {
                this.callback(this[result]);
            }
        }
    }
    return Request;
}

var RequestClosure = closure(Request);

const arr = [...Array(100).keys()];
new RequestClosure(arr, (res) => {
    console.log(res);
}).start();
发布了79 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_33807889/article/details/105153016