The race metaphor must not be taken too literally, but you can think of it as follows:
- The runner is an asynchronous process (like fetching a document from a web server or database, awaiting user input, or waiting for time to pass).
- The promise is a time-taker that reports when the runner crosses the finishing line (when the document or user input becomes available or the time has passed).
- The race winner is determined when the first time-taker reports the finishing result (aka winning time).
Even when a race has been won, the other time-takers involved (other than the one reporting the winning time) must continue watching their runners1, because they may be taking part in another race that they might still win. See the following example.
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);
If you want to avoid that behavior ("disqualify losers from other races"), you must program "race-is-over" awareness into the promise, like the over
variable in the example. If you bring in the commented-out line, the 1000 ms racer will no longer be able to win the second race.
(More precisely, if over = true
the runner setTimeout
will still finish, but the time-taker will not report any more. Race-is-over awareness is with the time-taker, not the runner. But in the case of a web server request, race-is-over awareness could instead be with the runner so that the request is aborted when the race is over.)
1 Another weakness of the metaphor: It is wrong to assume that the time-takers (promises) consume any resources while watching the runners.