Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk3 min

How to Flatten Nested Promises in JavaScript with async/await

Use sequential await expressions for dependent promise steps, Promise.all for independent work, and remember that an async function always returns a promise.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To flatten nested promise logic, move dependent asynchronous steps into an async function and await each result where the next step needs it. Return the final value. The async function still returns a promise, so its caller must await that promise or handle its result and rejection.

Rewrite nested .then() calls as a straight-line sequence

A nested callback often starts another asynchronous operation before the first callback has finished:

getUser(id).then((user) => {
  getPermissions(user.id).then((permissions) => {
    render(user, permissions);
  });
});

In an async function, await each dependent operation and use its result in the next step:

async function showUser(id) {
  const user = await getUser(id);
  const permissions = await getPermissions(user.id);
  return render(user, permissions);
}

const result = await showUser("123");

The second call cannot be made until the first returns the user, so the sequential awaits express the dependency directly. Returning render(...) makes its result the async function’s result.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If you keep a .then() chain instead, return the inner promise from the callback so the outer chain remains connected. MDN recommends keeping simple promise chains flat rather than nesting them; its promise guide also demonstrates the equivalent async/await style.

Understand what await and async return

await pauses the current async function’s continuation until its operand settles; it does not block the JavaScript main thread. When the promise fulfills, the await expression evaluates to its fulfillment value. When it rejects, the rejection reason is thrown at that expression. See MDN’s documentation for await and async functions.

An async function call always returns a promise, even if the function returns an ordinary value. Returning a promise from the function does not make its result synchronously available to the caller. The caller must await it or attach a handler, for example:

async function getLabel() {
  return "ready";
}

const label = await getLabel();

Promise resolution also assimilates promises and thenables returned from an async function: the caller’s promise adopts their eventual state rather than receiving a promise as its fulfilled value. This is not the same as recursively flattening arrays or arbitrary objects. await handles a promise or thenable result; it does not walk data structures. MDN explains thenable assimilation in its Promise constructor reference content.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose sequential awaits or concurrent work by dependency

Use sequential awaits when a later operation needs an earlier result:

const user = await getUser(id);
const permissions = await getPermissions(user.id);

If operations are independent, start both before awaiting their combined result with Promise.all:

const [user, settings] = await Promise.all([
  getUser(id),
  getSettings(id),
]);

The choice is about dependencies and timing, not syntax preference: sequential code starts the second expression after the first await resumes, while Promise.all aggregates the results of the supplied promises or thenables. Consider its rejection behavior and whether you need a different settlement policy; MDN documents the available Promise static helpers.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Handle rejections at the right boundary

An awaited rejection throws inside the async function, so ordinary try/catch can recover from it or add context. If the function does not need local recovery, let its returned promise reject and handle the failure at the caller:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
async function loadProfile(userId) {
  const response = await fetch(`/users/${userId}`);
  const user = await response.json();
  return fetchPermissions(user.id);
}

try {
  const profile = await loadProfile("123");
} catch (error) {
  console.error("Could not load profile", error);
}

Use return await when the local function needs the rejection to occur inside a local try/catch or finally. Otherwise, returning the final promise directly is generally sufficient:

async function loadPermissions(user) {
  return fetchPermissions(user.id);
}

Common pitfalls when flattening promise code

  • Forgetting the outer promise: calling an async function does not immediately give you its completed value. Await its result or attach fulfillment and rejection handlers.
  • Awaiting every return mechanically: await when you need the value locally or need a local error-handling boundary; otherwise, return the promise directly.
  • Confusing promise flattening with data flattening: promise resolution adopts nested thenables, but it does not recursively flatten arrays or object properties.
  • Treating every thenable as inert data: an object with a then property can be assimilated by await, even if it is not a native Promise. Be cautious when handling untrusted objects with custom then methods.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Shenzhen desk3 min
    HONOR Expands Beyond Smartphones With Humanoid Robot RevealHONOR said it unveiled its first humanoid robot at MWC 2026 and named shopping assistance, workplace inspections, and supportive companionship as intended uses. Later Robotics D1 claims and a reported…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.