Слияние кода завершено, страница обновится автоматически
import { action, IReactionDisposer, toJS } from 'mobx';
import Cache, { refreshCacheOptions } from '../cache';
const KEY = Symbol('KEY');
export default class PromiseMerger<K, ARGS, V> {
timeout: number;
cache: Cache<string, K>;
dataMap: Map<string, V>;
promiseMap: Map<string | symbol, Map<string, { resolves: Function[]; rejects: Function[] }>>;
waitID;
callback: (codes: string[], args: ARGS, dataList: V[]) => Promise<{ [key: string]: K }>;
reaction: IReactionDisposer;
constructor(callback: (codes: string[], args: ARGS, dataList: V[]) => Promise<{ [key: string]: K }>, config, timeout = 200) {
this.timeout = timeout;
this.promiseMap = new Map<string | symbol, Map<string, { resolves: Function[]; rejects: Function[] }>>();
this.cache = new Cache<string, K>(toJS(config));
this.dataMap = new Map<string, V>();
this.callback = callback;
this.reaction = refreshCacheOptions(this.cache);
}
dispose() {
this.reaction();
}
@action
add(code: string, getBatchKey: ((defaultKey: symbol) => string | symbol) | undefined, args: ARGS, data?: V): Promise<K> {
const { cache, promiseMap, dataMap } = this;
const item = cache.get(code);
if (item !== undefined) {
return Promise.resolve(item);
}
if (data) {
dataMap.set(code, data);
}
const batchKey = getBatchKey ? getBatchKey(KEY) : KEY;
return new Promise<K>((resolve, reject) => {
const promiseList = promiseMap.get(batchKey) || new Map();
promiseMap.set(batchKey, promiseList);
let promise = promiseList.get(code);
const resolveCallback = () => {
resolve(cache.get(code));
};
if (promise) {
promise.resolves.push(resolveCallback);
promise.rejects.push(reject);
} else {
if (this.waitID) {
clearTimeout(this.waitID);
}
promise = {
resolves: [resolveCallback],
rejects: [reject],
};
promiseList.set(code, promise);
this.waitID = setTimeout(() => {
const codeList: string[] = Array.from(promiseList.keys());
if (process.env.LOGGER_LEVEL === 'info') {
// eslint-disable-next-line no-console
console.info(`batch request: ${codeList}`);
}
this.callback(codeList, args, codeList.reduce<V[]>((list, $code) => {
const $value = dataMap.get($code);
if ($value !== undefined) {
list.push($value);
}
return list;
}, [])).then(res => {
codeList.forEach((key) => {
const value = promiseList.get(key);
promiseList.delete(key);
const { resolves = [] } = value || {};
if (res) {
const data = res[key];
this.cache.set(key, data);
resolves.forEach(r => r(data));
} else {
resolves.forEach(r => r());
}
});
})
.catch(error => {
codeList.forEach(key => {
const value = promiseList.get(key);
promiseList.delete(key);
const { rejects = [] } = value || {};
rejects.forEach(r => r(error));
});
});
}, this.timeout);
}
});
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )