once
Creates a function that can only be invoked once. Subsequent calls return the result of the first invocation. Ensures a function is executed exactly one time, regardless of how many times it's called. Useful for initialization functions, event handlers that should only fire once, or expensive operations that should only run once.
Installation
npx fragmen add function/onceSource Code
/**
* Creates a function that can only be invoked once. Subsequent calls return the result of the first invocation.
*
* Ensures a function is executed exactly one time, regardless of how many times it's called.
* Useful for initialization functions, event handlers that should only fire once, or
* expensive operations that should only run once.
*
* @tags performance
* @param {(...args: Args) => R} fn The function to restrict to a single execution.
* @returns {(...args: Args) => R} A new function that invokes fn only once and caches the result.
*
* @example
* ```typescript
* const initialize = () => {
* console.log('Initializing...');
* return { status: 'initialized' };
* };
*
* const initOnce = once(initialize);
*
* const result1 = initOnce(); // Logs: 'Initializing...', returns { status: 'initialized' }
* const result2 = initOnce(); // Does not log, returns cached result
* const result3 = initOnce(); // Does not log, returns cached result
*
* console.log(result1 === result2); // true - same reference
*
* // With parameters
* const createUser = (name: string) => {
* console.log(`Creating user: ${name}`);
* return { id: 1, name };
* };
*
* const createUserOnce = once(createUser);
* createUserOnce('Alice'); // Creates user
* createUserOnce('Bob'); // Ignores, returns Alice user
* ```
*/
export function once<T extends (...args: unknown[]) => unknown>(
fn: T
): (...args: Parameters<T>) => ReturnType<T> {
let called = false;
let result: ReturnType<T>;
return (...args: Parameters<T>): ReturnType<T> => {
if (!called) {
called = true;
result = fn(...args) as ReturnType<T>;
}
return result;
};
}
Examples
const initialize = () => {
console.log('Initializing...');
return { status: 'initialized' };
};
const initOnce = once(initialize);
const result1 = initOnce(); // Logs: 'Initializing...', returns { status: 'initialized' }
const result2 = initOnce(); // Does not log, returns cached result
const result3 = initOnce(); // Does not log, returns cached result
console.log(result1 === result2); // true - same reference
// With parameters
const createUser = (name: string) => {
console.log(`Creating user: ${name}`);
return { id: 1, name };
};
const createUserOnce = once(createUser);
createUserOnce('Alice'); // Creates user
createUserOnce('Bob'); // Ignores, returns Alice user
Related Utilities
debounce
functionCreates a debounced function that delays invoking the provided function until after wait milliseconds have elapsed. Prevents rapid successive calls by canceling previous timeouts. Useful for handling events like search input, button clicks, or window resize where you want to limit the frequency of function execution.
memoize
functionCreates a memoized version of a function that caches results. Caches function results based on arguments using a simple key-based cache. Improves performance for expensive pure functions by avoiding redundant calculations. Uses JSON.stringify for key generation.
throttle
functionCreates a throttled function that only invokes the provided function at most once per specified time period. Unlike debounce which delays execution, throttle ensures the function is called at regular intervals. The first call is executed immediately, and subsequent calls within the wait period are ignored. Useful for rate-limiting events like scroll, mousemove, or API requests.
Quick Actions
Tags
Parameters
fn(...args: Args) => RThe function to restrict to a single execution.
Returns
(...args: Args) => RA new function that invokes fn only once and caches the result.