Lodash _.before() method
What you’ll learn
- How
_.before(n, func)counts wrapper invocations and stops callingfuncafter the limit. - Why the documented
before(5, ...)pattern caps real work at four executions. - What callers observe once the wrapper freezes (cached return value).
- Try each example in the editor (
?tryit=1,2,3) with Lodash from a CDN.
Prerequisites
Optional reads Function hub, _.after(), and _.ary(); helpful to contrast guards that delay versus cap execution.
- Higher-order functions: storing mutable state in closures between calls.
- Return values: understanding that skipped invocations still return the last memoized result.
Overview
_.before(n, func) wraps func so it executes only while the wrapper’s internal counter (derived from n) stays positive after each decrement. Crossing the threshold freezes the last computed result and prevents further executions—ideal for UI caps such as “only four saves allowed.”
Hard stop
After enough clicks or callbacks, downstream logic cannot trigger func again through the same wrapper.
Memoized exit
Late callers still receive the final successful return without recomputation.
Tree-shakeable
Import lodash/before when you only need this guard.
Syntax
_.before(n, func) - n: threshold coerced with
toInteger; determines whenfuncstops running (aftern - 1successful calls). - func: must be a function or Lodash throws
TypeError: Expected a function. - Returns: a wrapper that forwards
thisand arguments while calls remain allowed; afterward returns the frozenresult.
Click-style cap (Lodash doc pattern)
before(5, fn) mirrors the official docs: the underlying work executes at most four times—the fifth press replays the fourth outcome without calling fn again.
import before from "lodash/before";
let count = 0;
const addContact = before(5, () => {
count += 1;
return count;
});
addContact(); // 1
addContact(); // 2
addContact(); // 3
addContact(); // 4
addContact(); // still 4 — frozen Side effects halt
Anything inside func—logging, DOM writes, network posts—runs only until the guard closes; extra wrapper calls short-circuit.
import before from "lodash/before";
const logTwice = before(3, (msg) => {
console.log(msg);
return msg.toUpperCase();
});
logTwice("a"); // prints, returns "A"
logTwice("b"); // prints, returns "B"
logTwice("c"); // silent — returns "B" before(2, fn) runs once
Smallest useful threshold: first invocation executes func; every later call replays that singleton outcome.
import before from "lodash/before";
const stamp = before(2, () => ({ id: Math.random() }));
const first = stamp();
const second = stamp();
first === second;
// true — same object reference returned 📋 _.before vs _.after
| Helper | Execution window | Mental model |
|---|---|---|
_.before(n, func) | First n - 1 wrapper calls | “Stop inviting work after enough tries.” |
_.after(n, func) | Starting at call n onward | “Wait for everyone to finish before continuing.” |
Need forever-once semantics without caring about counts? Prefer _.once.
Pitfalls to avoid
n = 1Nothing runs
The guard immediately blocks func; bump n or switch helpers if you expected one execution.
Miscounting allowances
Remember allowable executions are n - 1, not n, matching the Lodash documentation wording.
Ignoring new inputs
After freezing, fresh arguments are discarded—design APIs accordingly.
❓ FAQ
Summary
- Purpose:
_.before(n, func)permits at mostn - 1executions, then replays the final result. - Contrast:
_.afterdelays the first run;beforeends repeated runs. - Next: Lodash _.bind(), _.ary(), or official Lodash docs for _.before.
Once the internal counter reaches Lodash’s cutoff, before assigns func to undefined inside the closure—dropping the reference helps garbage-collection while later calls still return the memoized result.
6 people found this page helpful
