Skip to content

How to Use JavaScript Promise.allKeyed()

Learn how Promise.allKeyed() works, why named async results can be safer than array positions, how errors behave, and what to do about browser compatibility.

How to Use JavaScript Promise.allKeyed()

On this page

Firefox 155, released on September 1, 2026, adds support for Promise.allKeyed(), a new JavaScript promise-combination method that returns asynchronous results by name instead of array position. That small change can make code easier to read and less error-prone when several independent operations need to finish together. The feature is still experimental, so this tutorial shows how it works and where it is safe to use.Β 

Why Promise.all() Can Become Awkward

Promise.all() is useful when several asynchronous operations should run concurrently and the program should continue only after they all succeed. Its result is an array, however, so the code consuming that result must remember the exact order in which the promises were supplied. That becomes harder to maintain as a group of requests grows or changes. For example, swapping two entries in the input array without making the matching change during destructuring can silently associate a value with the wrong variable.

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

The operations above can still run concurrently, but their meaning depends on position: the first result is the user, the second is settings, and the third is notifications. Promise.allKeyed() keeps that relationship in the data itself by giving every promise a key. The result is an object using those same keys, so the code no longer depends on remembering an array's ordering.

Check the Environment Before Using Promise.allKeyed()

There is an important catch before writing production code. Mozilla lists Promise.allKeyed() as experimental, while the feature is defined by the TC39 Await Dictionary proposal, which is currently at Stage 3. Firefox 155 is the newly released browser implementation covered by Mozilla's developer documentation, so you should not treat this API as a universally available replacement for Promise.all().Β 

For a quick browser check, test whether the method exists before calling it.

if (typeof Promise.allKeyed === "function") {
  console.log("Promise.allKeyed is available");
} else {
  console.log("Use a compatible fallback");
}

That check does not make the API portable by itself, but it prevents unsupported browsers from failing immediately with a missing-method error. For applications serving multiple browsers, keep a fallback or use a suitable polyfill rather than assuming every visitor has Firefox 155 or newer support. MDN also points developers to polyfill options for the method.Β 

Start With Named Asynchronous Operations

Once the environment supports the method, the syntax is straightforward. Pass an object whose own enumerable properties contain promises or other values that can be awaited. The keys become the keys of the resolved result. Unlike an array-based approach, the names travel with the operations they describe.

const results = await Promise.allKeyed({
  user: getUser(),
  settings: getSettings(),
  notifications: getNotifications()
});

console.log(results.user);
console.log(results.settings);
console.log(results.notifications);

All three operations are started before the program waits for their combined result, so this is still a concurrency pattern rather than three sequential await statements. If every input promise fulfills, the returned object contains the corresponding values under the same keys. The order in which the individual operations finish does not change those names. ([MDN Web Docs][1])

Use Destructuring When You Only Need the Values

If the result object is only needed for a few local variables, JavaScript destructuring makes the pattern compact without bringing the ordering problem back. The property names remain visible at the point where each value is assigned. This is particularly useful when the asynchronous operations have different meanings rather than being a collection of interchangeable items.

const {
user,
settings,
notifications
} = await Promise.allKeyed({
user: getUser(),
settings: getSettings(),
notifications: getNotifications()
});

console.log(user);
console.log(settings);
console.log(notifications);

You can also rename a property while destructuring if the local variable needs a different name. The important distinction is that the association is made by the property name rather than by array position. That makes an accidental reorder much easier to spot during code review.

const {
user: currentUser,
settings: accountSettings
} = await Promise.allKeyed({
user: getUser(),
settings: getSettings()
});

console.log(currentUser);
console.log(accountSettings);

What Happens When One Promise Rejects

Promise.allKeyed() follows the failure behavior of Promise.all(): if one of its input promises rejects, the combined promise rejects with the rejection reason from the first promise to reject. It does not turn failed operations into successful result objects. That makes it appropriate when every operation is required before the next stage of the program can continue.Β 

try {
const data = await Promise.allKeyed({
profile: getProfile(),
account: getAccount(),
permissions: getPermissions()
});

console.log(data.profile);
} catch (error) {
console.error("A required operation failed:", error);
}

This behavior is worth deciding deliberately. If the page can still work when one request fails, rejecting the whole operation may be the wrong design. In that situation, the keyed version of Promise.allSettled(), called Promise.allSettledKeyed(), is the related API to investigate. Firefox 155 supports that method as well. ([MDN Web Docs][2])

Keep Nested Objects Out of the Promise Batch

The method processes the object's own enumerable properties; it does not recursively walk nested objects looking for promises. A nested object is treated as one value, so promises inside that nested object are not automatically awaited. This matters when converting an existing data structure because moving promises into another object layer does not make them part of the same keyed batch.Β 

const result = await Promise.allKeyed({
profile: getProfile(),
nested: {
settings: getSettings()
}
});

console.log(result.profile);
console.log(result.nested.settings);

In this example, profile is awaited because it is a direct property of the input object. The nested object itself is the value associated with that key, so its settings promise remains inside the nested object. If you need both operations awaited by the keyed combinator, put them at the level where the combinator can see them.

Know What Promise.allKeyed() Does Not Change

The new method does not make asynchronous work faster by itself. Its main improvement is how the inputs and outputs are associated with one another. If two network requests take roughly the same time, replacing Promise.all() with Promise.allKeyed() does not magically reduce their network latency; it gives the results meaningful names and removes dependence on array positions. That distinction matters because the feature is primarily a code-clarity and correctness improvement, not a performance benchmark.

It also does not remove the need for error handling. A rejected promise still rejects the combined operation, and browser compatibility remains a concern while the API is experimental. The TC39 proposal describes the feature as an object-based counterpart to Promise.all(), with the result retaining the input keys.Β 

Use a Fallback for Wider Browser Support

If your application cannot require a browser with native Promise.allKeyed() support, the safest approach is to keep using established JavaScript features or provide a tested compatibility layer. The same keyed behavior can be built with ordinary promises and an object of named operations, although that requires more code. MDN currently identifies polyfill implementations for developers who need to experiment with the API outside native support.Β 

const requests = {
user: getUser(),
settings: getSettings(),
notifications: getNotifications()
};

const [user, settings, notifications] = await Promise.all([
requests.user,
requests.settings,
requests.notifications
]);

const result = {
user,
settings,
notifications
};

This fallback preserves the basic idea but loses the direct native API that connects keys to results. For shared application code, that trade-off may still be preferable to depending on an experimental browser feature. If you are testing Firefox 155 specifically, however, Promise.allKeyed() gives you a cleaner way to express batches of differently named asynchronous tasks.

When Promise.allKeyed() Makes Sense

Use the keyed form when you have a small set of independent asynchronous operations with different meanings, especially when the results are naturally described by names such as profile, settings, and permissions. Stick with Promise.all() when you already have an array of similar operations or when array ordering is the natural representation of the data. The choice should follow the shape of the problem rather than the novelty of the API.

For now, the most sensible way to learn Promise.allKeyed() is to treat it as an experimental JavaScript concurrency feature rather than a universal replacement for Promise.all(). Firefox 155 gives developers a real implementation to test, while the TC39 proposal provides the underlying design and semantics. If the proposal continues toward standardization and broader engine adoption, code that uses named asynchronous results may eventually become a normal part of JavaScript rather than a browser-specific experiment.Β 

M

Written by

M. Rizwan Mirza

I’m M. Rizwan Mirza, a Full Stack Developer with over 12 years of experience in web development and software solutions. I work with modern web technologies and enjoy building practical, reliable, and user-friendly digital solutions. I’m also part of TechWare House, where I work on web development projects and technology solutions. One of my favorite websites is TheQuranic.com. Through WizTechnoz, I share my knowledge, experience, tutorials, and useful insights about technology.

44 posts published

All posts by this author

0 Comments

No comments yet. Be the first to share your thoughts.

Join the conversation

Log in or create a free account to leave a comment. You can edit or delete your own comments any time.