Lodash _.after() method

Beginner
⏱️ 6 min read
📚 Updated: May 2026
🎯 3 Code examples
🚀 3 Try-it labs
Lodash

What you’ll learn

  • How _.after(n, func) builds a wrapper that ignores func until enough calls arrive.
  • Why pairing n with saves.length (or task counts) models “all async jobs finished.”
  • How early calls differ from the first real invocation (return values and this forwarding).
  • Try each example in the editor (?tryit=1, 2, 3) with Lodash from a CDN.

Prerequisites

Optional read Lodash Function methods hub; you should be comfortable passing functions as arguments.

  • Closures: the wrapper remembers how many times it was invoked.
  • Function.prototype.apply: Lodash forwards this and arguments once the guard opens.

Overview

_.after(n, func) returns a new function. Each time that wrapper runs, Lodash decrements an internal counter derived from n; only when the counter falls below one does it call func with the current this and arguments. Until then the wrapper effectively no-ops (returns undefined).

Barrier pattern

Hand the same wrapper to every parallel completion path; the final caller triggers func once everyone checked in.

Opposite of before

_.before stops invoking after a limit; after withholds invocation until a threshold is crossed.

Tree-shakeable

Import lodash/after alone when this guard is all you need.

Syntax

javascript
_.after(n, func)
  • n: numeric threshold coerced with toInteger; controls how many wrapper calls occur before func runs.
  • func: must be a function or Lodash throws TypeError: Expected a function.
  • Returns: a new wrapper function forwarding this and arguments once the guard passes; earlier calls return undefined.
1

Parallel “done” callback

Pass one shared wrapper into every completion slot—mirrors the official Lodash docs pattern where n matches how many branches must finish.

javascript
import after from "lodash/after";

const saves = ["profile", "settings"];

const done = after(saves.length, () => {
  console.log("done saving!");
});

saves.forEach(() => {
  done(); // synchronous stand-in for asyncSave(..., complete: done)
});
Try it Yourself
2

Third call runs

With after(3, fn), the first two invocations decrement the guard only; the third finally executes fn and returns its result.

javascript
import after from "lodash/after";

const logThird = after(3, () => "third!");

logThird();
// undefined

logThird();
// undefined

logThird();
// "third!"
Try it Yourself
3

after(1, fn) on first call

When n is 1, the guard opens immediately on the first invocation—useful when you want identical ergonomics as other barriers but only one signal.

javascript
import after from "lodash/after";

const run = after(1, (msg) => msg.toUpperCase());

run("hello");
// "HELLO"
Try it Yourself

📋 _.after vs _.before

HelperWhen func runsTypical use
_.after(n, func)Starting at the nth wrapper callBarrier after N completions (often n = tasks.length)
_.before(n, func)Only while count < n; then freezesCap clicks or retries (first n - 1 calls invoke func)

Need exactly-once semantics forever? Combine patterns with _.once; after alone keeps calling func on every invocation after the gate opens.

Pitfalls to avoid

Off-by-one

Wrong n

If completions fire fewer than n times, func never runs; too many duplicate signals fire early.

n = 0

Immediate passthrough

Coerced zero removes the guard immediately—double-check dynamic lengths.

Duplicates

Extra invocations

After the barrier opens, every further call still hits func; gate again manually if you need exactly once.

❓ FAQ

Implicit undefined: early calls hit the guard branch that decrements n without returning the inner result.
On the invocation that drives the internal counter so that n drops below 1 after decrement—typically the nth call when n matches the number of parallel completions you counted.
before invokes func only while call count is below n (then freezes on the last result). after suppresses func until the wrapper has been hit at least n times, then delegates every subsequent call to func.
Lodash coerces with toInteger; after 0 the guard fires immediately so func runs on every invocation—usually accidental when you meant after(length).
Use import after from "lodash/after" so bundlers tree-shake unused Lodash.

Summary

Did you know?

Lodash positions _.after as the counterpart to _.before: after waits until the wrapper has been invoked at least n times, while before only lets func run during the first n - 1 invocations.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful