@livelybone/singleton
Version:
A util of singleton wrapping
136 lines (127 loc) • 4 kB
JavaScript
/**
* Bundle of @livelybone/singleton
* Generated: 2025-06-16
* Version: 1.3.8
* License: MIT
* Author: 2631541504@qq.com
*/
/**
* 每个单例的 id
*
* The id of a singleton
* */
function getIdsMap() {
var $global = typeof window !== 'undefined' ? window : global;
if (!$global.$$SingletonIdsMap || !($global.$$SingletonIdsMap instanceof Map)) {
$global.$$SingletonIdsMap = new Map();
}
return $global.$$SingletonIdsMap;
}
/**
* @deprecated 这个方法使用多了会导致内存泄漏,建议使用 singleton 方法代替
* @desc 返回 id 对应的一个单例对象
*
* Return a singleton of an object(such as Promise, Function, Object...) corresponding to the id.
* */
function singletonObj(id, defaultValue) {
var ids = getIdsMap();
var k = "singleton-any-".concat(id || 'default');
if (!ids.has(k)) {
ids.set(k, defaultValue ? defaultValue() : {});
}
return ids.get(k);
}
/**
* @desc 返回 id 对应的一个单例对象,这个方法应当配合返回的 delete 方法一起使用,否则使用多了会导致内存泄漏
*
* Return a singleton of an object(such as Promise, Function, Object...) corresponding to the id.
* This method will cause OOM if it's used too much without calling `delete`.
* */
function singleton(id, defaultValue) {
var ids = getIdsMap();
var k = "singleton-any-".concat(id || 'default');
if (!ids.has(k)) {
ids.set(k, defaultValue ? defaultValue() : {});
}
return {
get value() {
return ids.get(k);
},
delete: function _delete() {
return ids.delete(k);
},
update: function update(action) {
// @ts-ignore
var v = typeof action === 'function' ? action(ids.get(k)) : action;
ids.set(k, v);
return v;
}
};
}
/**
* @desc 保证一个 id 对应的 promise 在同一时间只存在一个,
* 并且生成 promise 的函数在 promise pending 状态的时间段内只执行一次,
* 这个方法可以用来减少同一时间的多余请求
*
* Ensure that only one promise corresponding to the id exists at the same time,
* and the function that generates the promise executes only once
* during the period of promise pending.
* This method can be used to reduce redundant requests at the same time
* */
function promiseOnPending(proFn, options) {
var ids = getIdsMap();
var id = options.id;
var cacheTime = options.cacheTime || options.delayTime;
var k = id ? "promise-".concat(id) : proFn;
var del = function del() {
return ids.delete(k);
};
var del1 = function del1() {
if (cacheTime === undefined) del();else setTimeout(del, cacheTime);
return true;
};
if (!ids.has(k)) {
ids.set(k, proFn().then(function (res) {
return del1() && res;
}, function (e) {
return Promise.reject(del1() && e);
}));
}
return ids.get(k);
}
/**
* @desc 封装 setInterval 函数,
* 保证同一个 id 对应的计时器只有一个在运行,
* 并且返回一个清除计时器的函数,方便随时终止计时器
*
* A wrapper of the setInterval function,
* make sure only one timer for the same id is running,
* and returns a function to clear the timer so it can be terminated at any time
* */
function runInterval(id, createFn) {
var ids = getIdsMap();
var k = "timer-".concat(id || 'default');
if (ids.has(k)) {
// clear old interval
ids.get(k)();
}
var $id = createFn();
ids.set(k, function () {
clearInterval($id);
ids.delete(k);
});
return ids.get(k);
}
/**
* @desc 保证传入的函数在程序的运行期间只运行一次
*
* Ensure that the incoming function runs only once during the run time of the program
* */
function onceRun(fn, id) {
var ids = getIdsMap();
var k = id ? "once-run-".concat(id) : fn;
if (!ids.has(k)) {
ids.set(k, fn());
}
}
export { onceRun, promiseOnPending, runInterval, singleton, singletonObj };