Node.js
callbacks
asynchronous programming
JavaScript
event-driven

How to make a function wait until a callback has been called using node.js

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Node.js, you usually do not make the whole process "wait" in a blocking sense. Instead, you structure your code so the next step runs only after the callback has fired, or you wrap the callback-based API in a Promise and await that Promise.

Do Not Busy-Wait or Block the Event Loop

The wrong instinct is to try to freeze execution until a callback happens. In Node.js, blocking the event loop prevents the callback from running in the first place, which defeats the model entirely.

The correct approach is asynchronous sequencing:

  • continue work inside the callback
  • return a Promise
  • use async and await

Continue the Flow Inside the Callback

The simplest pattern is just to put the dependent work in the callback itself.

javascript
1const fs = require('fs');
2
3fs.readFile('example.txt', 'utf8', (err, data) => {
4  if (err) {
5    console.error(err);
6    return;
7  }
8
9  console.log('Read complete');
10  console.log(data);
11});

This already "waits" logically, because the code that depends on the result runs only after the callback fires.

Wrap the Callback API in a Promise

If you want cleaner composition, wrap the callback-style function in a Promise.

javascript
1const fs = require('fs');
2
3function readFileAsync(path) {
4  return new Promise((resolve, reject) => {
5    fs.readFile(path, 'utf8', (err, data) => {
6      if (err) {
7        reject(err);
8        return;
9      }
10      resolve(data);
11    });
12  });
13}

Now the caller can wait on the Promise instead of nesting more callback logic.

Use async and await for Sequential Logic

Once you have a Promise, async and await make the code read more like straight-line logic.

javascript
1async function main() {
2  try {
3    const data = await readFileAsync('example.txt');
4    console.log('Read complete');
5    console.log(data);
6  } catch (err) {
7    console.error(err);
8  }
9}
10
11main();

This is usually the clearest way to express "do not continue until the callback-driven work is done."

Prefer Native Promise APIs When Available

Many modern Node.js APIs already provide Promise-based versions. If the API already supports await, use that instead of building your own wrapper.

javascript
1const fs = require('fs/promises');
2
3async function main() {
4  const data = await fs.readFile('example.txt', 'utf8');
5  console.log(data);
6}

This is simpler and less error-prone than manually wrapping every callback yourself.

Handle Errors on the Same Control Path

Whatever style you choose, keep success and failure handling tied to the same async flow. Callback code tends to become messy when errors are ignored or handled far away from the actual operation.

That is one reason Promise-based code usually scales better in larger applications.

Convert Gradually in Older Codebases

If you are working in a legacy callback-heavy Node.js service, you do not need to rewrite everything at once. Wrapping the most painful callback APIs behind Promise-returning helpers is usually enough to let new code use async and await cleanly.

Common Pitfalls

  • Trying to block the event loop while waiting for a callback.
  • Writing code after the callback registration and assuming it will run later automatically.
  • Wrapping callback APIs in Promises but forgetting to reject on error.
  • Mixing callbacks and Promises inconsistently in the same control flow.
  • Ignoring APIs that already provide built-in Promise support.

Summary

  • In Node.js, you do not block; you sequence async work correctly.
  • The dependent logic can run inside the callback itself.
  • For cleaner code, wrap callback APIs in Promises.
  • Use async and await when you want readable sequential-style flow.
  • Prefer native Promise-based APIs when the platform already provides them.

Course illustration
Course illustration

All Rights Reserved.