Promise.all vs. promise.race in JavaScript
A promise may depend on the completion of a list of operations and not only the result of a single processing.
We saw in the first part, Promise, it is possible to delay a processing, and to associate it with the future completion of a condition. And when the expected result happens, either succesful or not, the processing will be either made or not.
It is also possible to wait for not only the end of a process, but the end of a set of several processes. The Promise object has two different methods to treat it, all and race, and we'll see how they work in two examples.
Compatibility: Edge, Firefox, Chrome, Safari, Opera.
For information, the compatibility test code is as follows:
Promise.all([true]).then(function(result) {
document.getElementById("test").innerHTML = "Supported!";
});
Displays "Supported" if the all method of Promise is recognized, otherwise nothing is displayed.
Indeed, the parameter of the all method is an array of one element, true, so the result is always a success, but there is no result if the object is not implemented in the browser.
Promise.all
Promise.all leads to a success when all conditions are met, or results in failure when one of the conditions fails (without waiting for the others).
This method may be used when waiting the result of asynchronous processing and the processing to follow requires that all are successful.
The syntax of the method is as follows:
Promise.all( ... array of promises... ).then(fonction success, fonction fail)
The parameter of all is an array of objects of type Promise. One can also set values, they are converted internally by calls to promise.resolve.
The then method parameters has two functions, the first is performed on success (all elements of the array are successful) and the second on failure (an element at least has failed).
To illustrate this, you are asked to tick three boxes, and put them ON or OFF. Considerg ON as a success and OFF as a failure. The Promise.all method is based on what is selected to display "success" or "fail".
This demo has only a goal of explanation and is not necessarily of practical interest.
Check the three boxes:
HTML code:
<form name="pall">
<table>
<tr><td>Option 1 :
ON <input type="radio" name="r1" value="ON">
OFF <input type="radio" name="r1" value="OFF" checked>
</td></tr>
<tr><td>Option 2 :
ON <input type="radio" name="r2" value="ON" checked>
OFF <input type="radio" name="r2" value="OFF">
</td></tr>
<tr><td>Option 3 :
ON <input type="radio" name="r3" value="ON">
OFF <input type="radio" name="r3" value="OFF" checked>
</td></tr>
</table>
<input type="button" value="PROMISE" onclick="start()">
JavaScript code:
function checkRow(id) {
var y = document.pall[id];
return ((y[0].checked) ? true : false);
}
function p1(success, fail) {
if(checkRow("r1")) success(); else fail();
}
function p2(success, fail) {
if(checkRow("r2")) success(); else fail();
}
function p3(success, fail) {
if(checkRow("r3")) success(); else fail();
}
function overallSuccess() { document.getElementById("result").innerHTML = "Success!" }
function overallFail() { document.getElementById("result").innerHTML = "Fail." }
function start() {
var pa1 = new Promise(p1)
var pa2 = new Promise(p2)
var pa3 = new Promise(p3)
Promise.all([pa1, pa2, pa3]).then(overallSuccess, overallFail)
}
Promise.race
Promise.race sets the program pending the outcome of the first condition tested in a list. Depending on whether the result is a success or a failure, promise.race is a success or a failure, without awaiting the result of other conditions.
This statement may be used when a processing depends on another processing among several that have been triggered and the result of one is enough to continue. So you do not need all the processings to return a result.
To find a practical application, one must imagine that all triggered treatments depend on a single entity and that it determines their results.
The syntax is:
Promise.race( ... array of promises... ).then(fonction success, fonction fail)
Practical example
A client-side application wants to load an image on the server. It launches two operations, the first attempts to load the file via WebSocket, the second to load it with Ajax.
If one of the two operations can not find the file, it is a failure and it is transmitted to promise.race. As soon one of the two finds the file, it is a success and promise.race continues its processing, for example display the image.
Code:
function loadAjax(filename) {
... ajax code ...
}
function loadWebSocket(filename) {
... websocket code ...
}
var p1 = new Promise(function(success, fail) {
if(loadAjax("name.png")) success()
else fail()
})
var p2 = new Promise(function(success, fail) {
if(loadWebSocket("name.png")) success()
else fail()
})
function dispImage() {
... displays the image...
}
function dispError() {
... displays "not found"...
}
Promise.race( [p1, p2] ).then( dispImage, dispError )
See also: