BatchRequest

function toParamString(obj: any) {
    // string, number, boolean
    if (typeof obj !== 'object') {
        return JSON.stringify(obj);
    }
    // object , array
    const keys = Object.keys(obj);
    const entities = keys.sort().map((key) => {
        let value = obj[key];
        if (value === undefined) {
            value = null;
        } else if (typeof value === 'object') {
            value = toParamString(obj);
        }
        return `${key}$$$$${value}`;
    });
    return entities.join('@@@@');
}



class BatchRequest {
    constructor({deferMs = 100, useCache = true, onBatchRequest}) {
        this.useCache = useCache;
        this.deferMs = deferMs;
        this.onBatchRequest = onBatchRequest;
        this.reqCtxList = [];
        this.tryRequesTimeout = 0;
        this.cacheMap = {};
    }

    createDefer(cacheKey) {
        let _resolve
        let _reject
        const promise = new Promise((resolve, reject) => {
            _resolve = resolve
            _reject = reject
        });

        // 启用cache
        let _resolve2 = _resolve;
        if (this.useCache) {
            _resolve2 = (data)=>{
                this.cacheMap[cacheKey] = data;
                _resolve(data);
            }
        }

        return {
            promise,
            resolve: _resolve2,
            reject: _reject,
        }
    }

    tryRequest(){
        if (this.tryRequesTimeout) {
            clearTimeout(this.tryRequesTimeout);
            this.tryRequesTimeout = 0;
        }

        this.tryRequesTimeout = setTimeout(()=> {
            const reqCtxList = this.reqCtxList;

            this.reqCtxList = []; // 下次再请求,就用新的。
            this.tryRequesTimeout = 0; // 下次再请求,就用新的。

            this.onBatchRequest(reqCtxList);
        }, this.deferMs);
    }

    doRequest(param){

        const cacheKey = toParamString(param);

        // 本身有缓存。直接返回。
        if (this.useCache && this.cacheMap[cacheKey]) {
            const ss = this.cacheMap[cacheKey];
            return Promise.resolve(ss);
        }

        const defer = this.createDefer(cacheKey);

        const ctx = {param, defer};
        this.reqCtxList.push(ctx);
        this.tryRequest();
        return defer.promise;
    }
    
}

const batchRequestInstanceMap = {};

function getBatchRequest(name, onBatchRequest){
    let instance  = batchRequestInstanceMap[name];
    if (!instance) {
        instance = new BatchRequest({
            onBatchRequest
        });
        batchRequestInstanceMap[name] = instance;
    }
    return instance;
}

export {
    getBatchRequest,
    BatchRequest
}

  

posted on 2023-09-01 13:49  袜子破了  阅读(8)  评论(0编辑  收藏  举报