Can a promise callback be ever delayed?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Yes, a promise callback can absolutely be delayed. The important detail is what “delayed” means in JavaScript: a .then() or .catch() callback is scheduled as a microtask, so it does not run immediately, and it still has to wait until the current synchronous work finishes.
Promise Callbacks Are Asynchronous by Design
Even if a promise is already fulfilled, its callback does not run inline with the statement that attaches it. JavaScript schedules the callback to run after the current call stack unwinds.
The output is:
That is the first kind of delay: promise handlers are never truly immediate.
Microtasks Still Wait for the Current Stack
Promise handlers have higher priority than timer callbacks, but they are not magic. They cannot interrupt synchronous code that is already running.
In this example, the promise callback is delayed by the blocking loop. The promise is resolved immediately, but the callback cannot run until the thread becomes free.
This is the most common real-world reason a promise callback feels “late”: long-running synchronous work blocks the event loop.
Microtasks Versus Tasks
JavaScript engines generally process work in this order:
- run the current synchronous call stack
- drain the microtask queue
- move on to the next task, such as a
setTimeoutcallback or UI event
That means promise callbacks usually run before timer callbacks.
Typical output:
So promise callbacks are often sooner than timers, but they are still delayed until the synchronous phase finishes.
Other Ways Delay Can Happen
There are a few additional cases where the callback may appear delayed:
- the promise is resolved only after some other asynchronous operation finishes
- the main thread is blocked by CPU-heavy JavaScript
- the browser throttles background tabs, timers, or rendering-related work
- a large chain of microtasks is already queued ahead of the callback
The key point is that the delay is not random. It follows scheduling rules.
Practical Interpretation
When developers ask this question, they are usually trying to understand whether a promise callback can miss an expected ordering guarantee. The answer is:
- it will not run before the current synchronous code completes
- it usually runs before the next task queue item
- it can still be postponed by blocking code or by the later completion of the promise itself
So if your callback timing matters, the real thing to inspect is event-loop pressure, not the promise abstraction alone.
A Small Timing Demo
The already-resolved promise runs first among asynchronous callbacks, but only after the synchronous logging completes. The promise tied to setTimeout runs later because its resolution itself is delayed.
Common Pitfalls
A common mistake is assuming “resolved” means “callback runs right now”. In JavaScript, resolution schedules the handler; it does not execute it inline.
Another mistake is blaming promises for delays caused by synchronous CPU work. If the thread is blocked, every queued callback has to wait.
A third issue is comparing promise timing to setTimeout(fn, 0) and expecting them to behave the same. They use different queues and therefore different ordering rules.
Summary
- Promise callbacks are always asynchronous.
- They run as microtasks after the current synchronous stack finishes.
- They can be delayed by blocking JavaScript or by the promise resolving later than expected.
- They usually run before timer callbacks, but not before synchronous code.
- If timing looks wrong, inspect the event loop and any heavy synchronous work first.

