Forcing a function to wait until another function is complete
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In JavaScript, you usually do not "force" one function to wait by blocking the thread. Instead, you structure the code so the second function runs only after the first asynchronous operation has finished, typically with promises and await.
That distinction matters because JavaScript's event loop is designed around non-blocking execution. If you try to simulate waiting with busy loops or timing hacks, you make the program slower and less reliable without actually solving the coordination problem correctly.
If the First Function Is Synchronous
For synchronous functions, nothing special is required. JavaScript already executes them in order:
stepTwo runs only after stepOne finishes.
The problem appears when stepOne starts asynchronous work such as a timer, network request, or file operation.
Return a Promise and await It
Modern JavaScript solves this with promises:
await does not block the whole JavaScript runtime. It pauses the async function until the promise settles, which is exactly what you want for ordered async logic.
Chain Promises When You Cannot Use await
If you are in code that is not async, promise chaining works too:
This is still sequencing. The follow-up logic runs only after the first asynchronous operation resolves.
Callbacks Are the Older Pattern
Older APIs often use callbacks:
This works, but deeply nested callbacks become hard to read. Promises and async functions are usually cleaner.
Do Not Use Fake Waiting
Developers sometimes try patterns like:
- '
setTimeout(stepTwo, 1000)and hope step one is done in time' - busy loops that block the thread
- global flags checked repeatedly in intervals
These are all weak substitutes for actual completion signals. Time-based guesses fail when the first task is slower than expected, and blocking loops freeze the UI or event loop.
The right design is always the same: the first function should expose when it is done, and the second function should start from that signal.
A Practical Rule
If function B depends on the result of function A:
- make function A return a promise or accept a callback
- start function B only after A resolves or invokes the callback
That makes the dependency explicit and keeps your code honest about what is asynchronous.
Common Pitfalls
- Trying to block JavaScript instead of using a promise or callback.
- Forgetting to return the promise from the first function, which makes
awaituseless. - Using timers as guesses for completion instead of listening to the real completion event.
- Mixing callback and promise styles carelessly and making control flow harder to follow.
Summary
- Synchronous functions already run in order without extra work.
- For asynchronous functions, return a promise and use
awaitwhen possible. - Promise chaining and callbacks are alternative sequencing mechanisms.
- Do not use busy waits or guessed delays to coordinate async code.
- The correct pattern is to run the second function from the first function's real completion signal.

