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 }