These two generalize once. before(n, fn) lets a function run only its first n − 1 calls, then returns the last result forever after — once is exactly before(2, fn). after(n, fn) is the mirror: it stays quiet until the nth call, then runs — the classic "do this once all N async tasks report back."
Implement both. before(n, fn) invokes fn while it has been called fewer than n times, caching the last result afterward. after(n, fn) invokes fn only from the nth call onward.
function before(n, fn) {} // runs fn for the first n-1 calls, then caches
function after(n, fn) {} // runs fn only from the nth call onward
const init = before(2, setup); // like once: runs setup on the 1st call only
init(); init(); // setup ran once
const done = after(3, () => console.log('all loaded'));
done(); done(); // nothing
done(); // 'all loaded' — the 3rd call fires it
before(n, fn) — invokes fn on calls 1 … n−1; call n and beyond return the last result without invoking fn.once is before(2, fn) — runs on the first call, caches from the second.after(n, fn) — the first n−1 calls are no-ops (return undefined); the nth call and every one after invoke fn.this and args — both pass the caller's this and arguments through to fn.