Competing in a fast-paced race with JavaScript promises to guarantee the completion of all

How can I retrieve the result of a Javascript Promise that resolves the fastest, while still allowing the other promises to continue running even after one has been resolved? See example below.

// The 3 promises in question
const fetchFromGoogle: Promise<T> = googlePromise()
const fetchFromAmazon: Promise<T> = amazonPromise()
const fetchFromCloudflare: Promise<T> = cloudflarePromise()

// Retrieve the result of the fastest resolving promise
const winner: T = Promise.race([fetchFromGoogle, fetchFromAmazon, fetchFromCloudflare])

If, for example, the fetchFromAmazon call wins in terms of speed, its result will be returned to the client, but the other two promises will continue executing asynchronously.

This code is running within a Cloudflare Worker, and the functionality to return the winning promise while allowing the evaluation of the others can be achieved using the waitUntil API linked below.

I have considered two options:

  1. An unknown Javascript API that may handle this automatically
  2. Using a method like this to identify the "losing" promises and execute them with Cloudflare Workers' context.waitUntil function to ensure continuous evaluation despite already returning a result to the client.

I believe that utilizing Promise.all would not meet this requirement, as it would wait for all three promises to complete before returning any result.

Answer №1

If you want to handle multiple promises and only care about the first one that finishes, you can use a combination of the .then() handler with Promise.race(). The .then() allows you to process each result individually, while Promise.race() signals when the first promise is complete:

// Three promises we are interested in
const fetchFromGoogle: Promise<T> = googlePromise().then(result => { 
    /* process this one here whenever it completes */
    return someValue;
});
const fetchFromAmazon: Promise<T> = amazonPromise().then(result => { 
    /* process this one here whenever it completes */
    return someValue;
});
const fetchFromCloudflare: Promise<T> = cloudflarePromise().then(result => { 
    /* process this one here whenever it completes */
    return someValue;
});

// Get the value of the first completed promise
const winner: T = await Promise.race([fetchFromGoogle, fetchFromAmazon, fetchFromCloudflare]);

Note that Promise.race() resolves once the first promise settles, regardless of success or failure. If the first promise rejects, that is what Promise.race() will return. Use Promise.any() if you specifically want the first fulfilled promise.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

React.Suspense is looking for a different type of data following the update

After a recent update, I encountered an issue with my React.Suspense fallback triggering this error message: Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefine ...

The p5.play library does not function properly on repl.it

I've recently started using p5.play, but I keep encountering this error whenever I try to run a program (I'm using repl.it); p5 is having issues creating the global function "Animation", possibly because your code already uses that name as a va ...

Translate3d increases the whitespace towards the end of the page

After implementing a smooth scroll on my webpage using transform translate3d, I encountered an issue. The translate3d function seems to be adding extra space at the end of the document, as illustrated here: https://codepen.io/anon/pen/WEpLGE I suspect the ...

Error 431 is encountered when submitting an Axios post request

Facing a 431 (Request Header Fields Too Large) error when trying to submit a form in my single-page project through an axios request. I've attempted setting maxContentLength and maxBodyLength to Infinity, as well as adding max-http-header-size in the ...

The Fixed Navbar is causing sections to be slightly off from their intended positions

Utilizing a bootstrap navigation menu on my website with a fixed position. When clicking a menu item, it takes me to the designated section but slightly above the desired position. How can I ensure that it goes to the exact position upon clicking the men ...

How to show line breaks in MySQL text type when rendering in EJS

In my MySQL table, I have a column called PROJ_ABOUT with the type TEXT. I have inserted several rows into this column and now I am trying to display this information in my Express.js app using the ejs engine. <h2>About project</h2> <p> ...

Are there any techniques for running unit tests on a Vue.js transition?

I have been working on a Vue component that includes a transition with a dynamically generated name. My challenge is to test whether the transition name is correctly set based on the props I pass into the component. Below is the code snippet of the compone ...

Having trouble with your React/TypeScript/Redux/Thunk action not dispatching and the state remaining unchanged?

Currently, I am facing an issue while attempting to send a GET request to an API using React-Redux & TypeScript. The goal is to dispatch an action upon clicking a button (onClick event), make the request, update the state via the reducer, and finally log t ...

Is it feasible to create a doughnut chart with curved edges?

My goal is to create a doughnut chart, but my search for reliable CSS/SVG/Canvas solutions has not been successful. https://i.sstatic.net/Rq6Lx.jpg I want each segment to have fully rounded corners, which presents a unique challenge. ...

Sorting in MongoDB aggregation operations

I have a database containing user activities, and I want to calculate the number of active users and activities they performed each month. The results should be sorted by year first and then by month within each year. Here is my query: query = { ...

When using Vuetify's v-text-field with the type "number", remember to assign a null value instead of an empty string

One issue I've encountered is that when using v-text-field with the type="number" attribute, the value is set to an empty string after manual clearing. Ideally, I would like it to return null in such instances. Is there a way to set an attr ...

Attempting to grasp the concept of Typescript generics

I have a function defined as follows: interface ExtraModels extends Model { unknown: string } const write = async (data: ExtraModels[]) => { console.log(data[0].unknown) } This function is currently working. However, I want to modify it to: cons ...

Using Jquery to retrieve data in sections from a server and continuously add it to a file on the client side

I have a large dataset stored in JSON format on a Postgres Server with hundreds of thousands of rows. To prevent memory overload on the server, I need to provide users with the ability to download the data in chunks rather than all at once. This requires a ...

Efficient method to update the state of a result in React JS using hooks within an asynchronous function and useState

How can I ensure the state is updated correctly after using setState? I found a code example similar to mine at Why react hook value is not updated in async function?, but it doesn't provide a solution to the problem. Any help would be greatly appreci ...

Creating Bootstrap Popover dynamically on a jQuery DataTable is a straightforward process that can enhance user experience

I am currently populating a table with data retrieved from an ajax call. The filling process is done through the use of append method as shown below: var table = //something //loop through ajax response objects table.append('<tr><td>&apo ...

Accessing stored web pages / Browser as an interactive interface

I have a couple of questions I need help with. The first one is about how to open a saved HTML file in a browser without an internet connection. Next, I'm looking for advice on using the browser as a user interface for a desktop image viewing program ...

How can I trigger my function in jQuery after inputting into the jQuery text field?

Looking for advice on implementing a function in jQuery for a text field that is not working as expected. The code works fine when creating a text field in HTML, but encounters issues with the jQuery text field. <!DOCTYPE html> <html> <body ...

Oops! There seems to be an issue with trying to access the 'map' property of undefined within the render method

While working on my project, I encountered an issue with a table from react material ui. The problem arises when attempting to populate the table with data from the state, resulting in an error message stating "cannot read property 'map' of undef ...

What is the best way to preserve the state of child components after being filtered by the parent component?

I've been working on a small application using create react app to enhance my skills in React, but I've hit a roadblock with managing the state. The application maps through JSON data in the parent component and displays 6 "image cards" as child ...

The Johnny-Five stepper initiates movement within a for-loop

I am new to using node.js and johnny-five. I want to move a stepper motor 5 times with 1000 steps each. Here is what I have tried: do 1000 Steps in cw ; console.log('ready); do 1000 steps; console.log('ready') ... It woul ...