Promise in JavaScript: waiting for the result of a process

To perform a processing that depends on the completion of another, Promise object is used. A simple demonstration.

This object is especially useful when you expect a series of results to continue operations. It simplifies the code. It complements the setTimeout method expecting the end of a delay to perform an action, and listeners that respond to user actions. Promise reacts to the completion of a process.

One might ask, why not put the code that depends on the completion, after this one? Because the second works in asynchronous mode, and has no connection with the code that calls it. But it will be clearer in the demonstration below.

Promise is implemented on all browsers, but an still large proportion of browsers does not support it. So we will use it in a modern application or server side. There are also extensions available on GitHub to add this feature to older browsers.

Syntax

The constructor of the promise object has an argument, a function which represents the processing to be completed before you can continue.

The method then of an instance of the object is called with two functions for arguments. These arguments are two functions which were previously defined. When the expected processing is completed and successful, it calls the first function. If it fails, it calls the second function.

Now we will see this in an example:

1) A utility function to display the result

function display(message) {
  document.getElementById("storage").innerHTML = message;
}

2) The processing whose we wait the result

The function has two other functions as arguments. One or the other is called depending if the process is a success or a failure, and they have a message or a result for argument.

var A = 10;
var B = 5;

function p(success, fail) {
  if(A + B == 15) 
    success("It is a success");
  else
    fail("An error occured");
}

3) Definition of delayed processing which responds to the pending process

Two functions are defined, the one which is called when the processing is completed and successful, and the other to signal an error.

function good(res) {
  display(res);
}

function bad(res) {
  display(res);
}

In a real application, of course we will do more than just displaying a message as in this minimalist example.

4) Declaration of an instance of Promise and call to then

An instance of Promise is declared, with the function whose result is expected for parameter of the constructor, then the then method is called on this instance with two parameters, the functions that react to a success or to an error.

var promise = new Promise(p);
promise.then(good, bad);

5) Result

Result

6) Counter-example

We will create a new instance of the same object Promise, but this time the result depends on a value selected by you.

Enter a number in the text field below and click the button. This number will be assigned to variable B. If the value is different from 5, the script should display "An error occured" in the result box above.

Here is the source code:

<input id="userval" type="text" value=""><input type="button" onclick="setVal('userval')" value="Click">
<script>
var A = 10;
var B = 5;

function p(success, fail) {
  if(A + B == 15) 
    success("It is a success");
  else
    fail("An error occured");
}

function good(res) {
  display(res);
}

function bad(res) {
  display(res);
}

function setVal(id) {
  B = parseInt(document.getElementById("userval").value);
  var promise1 = new Promise(p);
  promise1.then(good, bad);
}
</script>

It is possible to write the above code in the form of callback. This would be less readable and we could not reuse the functions ... whose nature is to be reused. Unlike the instance of Promise that can be used only once, according to my tests, this why we have to declare promise1.

Second part: Promise.all vs promise.race. Going further with the object Promise and managing several concurrent processings.

See also ...

© May 7, 2015 - Updated in 2017 Xul.fr