Last callback not being called using async
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
When the "last callback" in asynchronous JavaScript never runs, the root cause is usually not randomness in the event loop. It is almost always a control-flow bug: a promise chain that never resolves, a callback path that is skipped on one branch, or a thrown error that stops execution before the final callback is reached.
The First Rule: Every Async Path Must Finish
If one branch neither resolves nor rejects, the code waiting for completion has nothing to continue from.
In this example, the final callback is not "mysteriously ignored." The code simply never called it when flag was false.
Mixing Callbacks and async Functions Causes Confusion
Another common issue is mixing callback-based APIs with async and await in a way that leaves one completion style hanging.
This is fine if the caller truly expects a callback. But if the surrounding framework expects you to return a promise instead of calling done, or expects done without any returned promise semantics, the control flow becomes muddy quickly.
Choose one pattern for a function:
- callback-based completion
- promise-based completion
Do not casually combine both unless the framework explicitly supports it.
Errors Can Stop the Final Callback Before It Runs
If an exception is thrown inside async code and never handled, later steps may never execute.
Without the try and catch, a rejection from saveItem could short-circuit the rest of the function, making it look as though the final callback was skipped for no reason.
Array Helpers Are a Frequent Trap
Developers often use forEach with async callbacks and expect the surrounding code to wait.
Here done() runs immediately, before any of the saveItem calls finish. The opposite bug can also happen if the final callback is placed somewhere that is never reached after asynchronous fan-out.
If you need to wait for everything, use Promise.all or a for...of loop.
Debug the Completion Boundary
When the last callback is missing, log every place that should lead to completion:
The goal is to find the exact branch where the flow stops. Once you know that, the bug is usually one of:
- callback never invoked
- promise never resolved
- error thrown before final step
- function returned too early
Common Pitfalls
The biggest pitfall is assuming every branch eventually calls the callback. In callback-heavy code, one missing return done(...) on an error path is enough to make the whole function hang.
Another common mistake is mixing promise and callback styles in the same function without defining which one actually signals completion. That often leads to double-calls, missed calls, or code that completes too early.
Developers also misuse forEach with async functions and then blame the event loop, when the real problem is that forEach does not wait for asynchronous work.
Summary
- A missing final callback usually means one async path never completed correctly.
- Make sure every branch either calls the callback or resolves or rejects the promise.
- Do not mix callback and promise styles casually in the same function.
- Handle errors explicitly so they do not silently skip the final completion step.
- If async loops are involved, prefer
for...oforPromise.alloverforEach.
Related reading
- latchused for awaiting async response freezes the WebView and the UI
- libev custom events
- Limit number of cores used in Keras
- Limiting requests with the async and request modules
- Limit file format when using <input type=file>?
- Limit text length to n lines using CSS
- Launch iOS simulator from Xcode and getting a black screen, followed by Xcode hanging and unable to stop tasks
- Launch Screen storyboard not displaying image
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.