before()
before<
Args,Return>(func,n): (...args) =>Return|undefined
Creates a function that invokes func at most n-1 times. Subsequent calls return the result of the last invocation.
When n โค 1, func is never invoked and undefined is always returned.
Type Parametersโ
Args: Args extends unknown[]โ
The argument types of the function.
Return: Returnโ
The return type of the function.
Parametersโ
func: (...args) => Returnโ
The function to restrict.
n: numberโ
The number of calls at which func is no longer invoked.
Returnsโ
The new restricted function. Returns undefined until func is first invoked.
Throwsโ
RangeError If n is negative or not an integer.
See Alsoโ
after - Inverse operation: invokes func only after n calls.
Sinceโ
2.0.0
Also known asโ
before (Lodash, es-toolkit) ยท โ (Remeda, Radashi, Ramda, Effect, Modern Dash, Antfu)
Exampleโ
let count = 0;
const increment = before(() => ++count, 3);
increment(); // => 1
increment(); // => 2
increment(); // => 2 (no longer invoked)
increment(); // => 2
// Use case: Initialize only once
const initialize = before(() => {
console.log('Initializing...');
return { ready: true };
}, 2);
initialize(); // "Initializing..." => { ready: true }
initialize(); // => { ready: true } (cached)
How it works?โ
Creates a function that invokes at most n-1 times.
After n-1 invocations, subsequent calls return the last result.
before vs afterโ
| before(fn, 3) | after(fn, 3) | |
|---|---|---|
| Call 1 | executes | skips |
| Call 2 | executes | skips |
| Call 3+ | cached | executes |
Use Casesโ
Limited Retries for operations ๐โ
Limit the number of retry attempts for operations. Essential for resilient error handling.
import { before } from "pithos/arkhe/function/before";
const attemptConnection = async () => {
const response = await fetch("/api/health");
if (!response.ok) throw new Error("Connection failed");
return response.json();
};
// Allow only 3 attempts (calls on 1st, 2nd, 3rd - returns last result after)
const limitedRetry = before(attemptConnection, 4);
async function connectWithRetry() {
for (let i = 0; i < 5; i++) {
try {
const result = await limitedRetry();
if (result) return result;
} catch (e) {
console.log(`Attempt ${i + 1} failed`);
}
}
throw new Error("All retries exhausted");
}
One-time Initialization ๐โ
Ensure initialization code runs only once. Critical for singleton patterns and setup.
import { before } from "pithos/arkhe/function/before";
const initializeApp = () => {
console.log("Initializing application...");
// Heavy setup: load config, connect to DB, etc.
return { initialized: true, timestamp: Date.now() };
};
// Only actually initialize on first call
const safeInit = before(initializeApp, 2);
// First call initializes
const result1 = safeInit(); // Logs "Initializing application..."
console.log(result1); // { initialized: true, timestamp: ... }
// Subsequent calls return the cached result
const result2 = safeInit(); // No log, returns same result
console.log(result1 === result2); // true (same reference)
Rate Limited Actions for user interactionsโ
Limit how many times a user action can trigger. Important for preventing spam clicks.
import { before } from "pithos/arkhe/function/before";
const submitForm = (data: FormData) => {
console.log("Submitting form...");
return fetch("/api/submit", { method: "POST", body: data });
};
// Allow only 1 submission (before 2nd call)
const limitedSubmit = before(submitForm, 2);
// In form handler
form.addEventListener("submit", async (e) => {
e.preventDefault();
const data = new FormData(form);
// Only first click actually submits
const result = await limitedSubmit(data);
if (result) {
console.log("Form submitted successfully");
} else {
console.log("Form already submitted");
}
});
executes
skips
cached