In Promise.race(), what is the fate of promises that don't come out on top

Promise.race(promise1, promise2, ...)
function returns a promise that resolves or rejects based on the fastest promise from the input list.

But what happens to the promises that do not win the race?

My experiments with Node.js suggest that they keep running in the background.

It seems like there is no mechanism to forcefully terminate a promise. Is this understanding accurate?

Answer №1

Every promise in a race continues to run even after the first one finishes -

const sleep = ms =>
  new Promise(r => setTimeout(r, ms))

async function runner (name) {
  const start = Date.now()
  console.log(`${name} sets off on the race`)
  await sleep(Math.random() * 5000)
  console.log(`${name} completes the race`)
  return { name, delta: Date.now() - start }
}

const runners =
  [ runner("Alice"), runner("Bob"), runner("Claire") ]

Promise.race(runners)
  .then(({ name }) => console.log(`!!!${name} is the winner of the race!!!`))
  .catch(console.error)
  
Promise.all(runners)
  .then(JSON.stringify)
  .then(console.log, console.error)

Alice sets off on the race
Bob sets off on the race
Claire sets off on the race
Claire completes the race
!!!Claire is the winner of the race!!!
Alice completes the race
Bob completes the race
[ 
  {"name":"Alice","delta":2158},
  {"name":"Bob","delta":4156},
  {"name":"Claire","delta":1255}
]

Answer №2

While the race metaphor may not be meant to be taken literally, it can be understood in the following way:

  • Think of the runner as an asynchronous process (such as fetching a document from a web server or database, awaiting user input, or simply waiting for time to pass).
  • The promise acts as a time-keeper that notifies when the runner crosses the finish line (when the document or user input is available, or when the designated time has elapsed).
  • The winner of the race is determined by the first time-keeper that announces the result (also known as the winning time).

Even after one race is won, other time-takers (aside from the one declaring the victory) must still monitor their runners1, as they might be participating in another race where they could emerge victorious. An example is provided below.

var over;
function runner(ms) {
  return new Promise(function timetaker(resolve, reject) {
    setTimeout(function() {
      if (!over) resolve(`Finished after ${ms} ms`);
    }, ms);
  });
}
function endofrace(result) {
  console.log(result);
  //over = true;
}
var veryslow = runner(2000);
var slow = runner(1000);
var fast = runner(500);
Promise.race([slow, fast]).then(endofrace);
Promise.race([slow, veryslow]).then(endofrace);

To prevent certain behaviors ("disqualifying losers from other races"), you need to implement "race-is-over" awareness into the promise, similar to the over variable in the example. By uncommenting the specified line, the racer with a duration of 1000 ms will no longer have a chance to win the second race.

(Specifically, if over = true, the runner's setTimeout will still complete, but the time-keeper will cease reporting further results. The awareness of the race being over lies with the time-keeper, not the runner. Alternatively, in the context of a web server request, the race-is-over awareness could reside with the runner to abort the request once the race concludes.)


1 Another limitation of the metaphor: It is inaccurate to assume that time-takers (promises) consume resources while observing the runners.

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

Obtaining user data in Angular post login

My goal is to retrieve user data and display it anywhere on my website. For example, I want to fetch the user's name and show it on the homepage once they are logged in. Any suggestions? Thank you AuthService import { Injectable } from '@angula ...

Adding a fresh element and removing the initial item from a collection of Objects in JavaScript

I'm working on creating an array of objects that always has a length of five. I want to push five objects initially, and once the array reaches a length of five, I need to pop the first object and push a new object onto the same array. This process sh ...

React: The error message "p is not defined" is showing up in the component file due to the no-undef

In my React application, I am looking to display a list of menu items from an array and show the detailed description of each item upon clicking. The array of menu items is stored in a separate file called dishes.js. The menu items are rendered using a Me ...

Element dynamically targeted

Here is the jQuery code I currently have: $('.class-name').each(function() { $(this).parent().prepend(this); }); While this code successfully targets .class-name elements on page load, I am looking to extend its functionality to also target ...

What is the best way to conceal a Boostrap Navbar using jQuery?

Attempting to create a hidden side navbar using Jquery and Bootstrap 4. Struggling with the .on('click', ...) event handler for a button not hiding the sidebar as expected despite all files loading correctly according to the developer tools. Atte ...

Encountering issues when setting fitbounds beyond the scope of a jquery.each()

I am currently working on a Google Map project using JavaScript(v3). My goal is to display markers from XML data by utilizing jQuery. Below are the object and function that I have created to streamline this process: var VX = { map:null, bounds ...

Using a percentage width on a <div> element with the "overflow-x: scroll" property does not seem to be functioning properly, even when encapsulated within

My code includes a div within another div, taking up 50% of the page's width: <div id="mainContainer" class="mainContainer"> <div id="scroller" class="scrolling"> <!-- items here should make the div really long --> & ...

Customizing content based on Route - Utilizing Node.js/React

I am currently working on setting up routes for different pages of store profiles in my Node app. I have been doing some research online and have come to understand how to adjust the parameters, but I am struggling with figuring out how to dynamically chan ...

Utilize the power of PIXI.js to effortlessly convert your canvas into a high-quality image without encountering

I'm currently working on exporting the entire canvas as a PNG using PIXI.js within a React app that incorporates react-pixi. My version is 6.5 and I've been trying out the following code: // MyComponent.tsx <button onClick={exportImage} /> ...

React Native: A guide to triggering a modal or action sheet when a button tab is clicked using Wix React Native navigation

Is it possible to trigger a modal or actionsheet by clicking on a specific bottom tab in a tab-based application using wix react native v2 navigation? These are the current packages and versions I am working with: react-native : "0.59.8" react : "16.8. ...

Express JS get method causing browser tab to hang with continuous loading

After deciding to create my first REST API using Express.js, I embarked on the journey of exploring this new technology. To kickstart the process, I opted to utilize the Express application generator by running npx express-generator. Following that, in th ...

Problems with Angular functionality

I'm a newbie when it comes to Angular and I'm eager to start practicing some coding. I've put together a simple app, but for some reason, the Angular expression isn't getting evaluated in the browser. When I try to display {{inventory.p ...

Execute Cheerio selector once the page has finished loading

Hey there! I'm trying to extract the URL value of an iframe on this website: I've checked the view page source but couldn't find the iframe. Looks like it's loaded after the page is fully loaded through JavaScript. Could it be that ...

ReactJS encountered an error of type ERR_INVALID_ARG_TYPE

Hello there! I recently purchased a template from ThemeForest and everything was working perfectly with the previous version. However, upon updating to the new version, I encountered an error that looks like this: > TypeError [ERR_INVALID_ARG_TYPE]: Th ...

Transmit information between controllers during pageload in AngularJS without utilizing $rootscope

I currently have 2 controllers set up as follows: app.controller('ParentMenuController', function ($scope,MenuService) { $scope.contentLoaded = false; $scope.showButton = false; $scope.showButton = MenuService ...

Exploring the world of JSON files using JavaScript

Basically, my bot responds to a command (!accounts) by providing users with information based on their ID. For example, if an ID of 662 sends the command !account, the bot will search for steamID 662 in the json files and display the currency and correspon ...

Building a dynamic form in React: Fetching select data from an API, posting to another API, and automatically clearing fields upon submission

I am currently working on a form that utilizes a GET request to retrieve data from an API endpoint and then proceeds to make a POST request to another endpoint. Although I have been successful in achieving this function, I am facing challenges with reset ...

Refreshing data attribute following an ajax request

I have this page with a list of various job listings. Each job listing has a button labeled "Paid" that includes a data-paid attribute indicating whether the job is paid or not. Whenever the "Paid" button is clicked, it sends a request to my route which u ...

Vue: Conditionally display a division depending on v-if, excluding cases where the div returns null

Within my HTML, I have implemented conditional rendering using v-if <div v-if="showdiv"> <p>Content 1 appears here</p> </div> <div v-if="!showdiv"> <p>Content 2 appears here</p> < ...

Hiding labels using JQuery cannot be concealed

Why isn't this working? -_- The alert is showing, but nothing else happens. <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeaderContent"> <script type="text/javascript"> if (navigator.userA ...