@ayonli/jsext
Version:
A JavaScript extension package for building strong and modern applications.
47 lines (44 loc) • 1.11 kB
text/typescript
const uninitialized = Symbol("uninitialized");
/**
* Creates a function that performs lazy initialization on the first call and
* returns the same result on subsequent calls.
*
* @example
* ```ts
* import once from "@ayonli/jsext/once";
*
* // sync
* const getMap = once(() => new Map());
* (() => {
* const map1 = getMap();
* map1.set("key", "value");
* console.log(map1.get("key")); // "value"
*
* const map2 = getMap();
* console.log(map1 === map2); // true
* })();
*
* // async
* const getDb = once(async () => {
* const db = await connectToDb();
* return db;
* });
* (async () => {
* const db1 = await getDb();
* const result = await db1.query("SELECT * FROM users");
* console.log(result);
*
* const db2 = await getDb();
* console.log(db1 === db2); // true
* })();
* ```
*/
export default function once<T>(init: () => T): () => T {
let value: T | typeof uninitialized = uninitialized;
return () => {
if (value === uninitialized) {
value = init();
}
return value;
};
}