How do promises work in JavaScript?

A promise is basically an object with two methods. One method is for defining what to do, and one is for telling when to do it. It has to be possible to call the two methods in any order, so the object needs to keep track of which one has been called:

var promise = {
  isDone: false,
  doneHandler: null,
  done: function(f) {
    if (this.isDone) {
        f();
    } else {
        this.doneHandler = f;
    }
  },
  callDone: function() {
    if (this.doneHandler != null) {
        this.doneHandler();
    } else {
        this.isDone = true;
    }
  }
};

You can define the action first, then trigger it:

promise.done(function(){ alert('done'); });
promise.callDone();

You can trigger the action first, then define it:

promise.callDone();
promise.done(function(){ alert('done'); });

Demo: http://jsfiddle.net/EvN9P/

When you use a promise in an asynchronous function, the function creates the empty promise, keeps a reference to it, and also returns the reference. The code that handles the asynchronous response will trigger the action in the promise, and the code calling the asynchronous function will define the action.

As either of those can happen in any order, the code calling the asynchronous function can hang on to the promise and define the action any time it wants.


For the simplicity to understand about the promises in Javascript. You can refer below example. Just copy paste in a new php/html file and run.

<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">

function test(n){
    alert('input:'+n);

    var promise = new Promise(function(fulfill, reject) {         
      /*put your condition here */
      if(n) {
        fulfill("Inside If! match found");
      }
      else {
        reject(Error("It broke"));
      }
    });
    promise.then(function(result) {
      alert(result); // "Inside If! match found"
    }, function(err) {
      alert(err); // Error: "It broke"
    });
}

</script>

</head>
<body>
<input type="button" onclick="test(1);" value="Test"/>

</body>
</html>
  1. Click on Test button,
  2. It will create new promise,
  3. if condition will be true it fulfill the response,
  4. after that promise.then called and based on the fulfill it will print the result.
  5. In case of reject promise.then returns the error message.

Probably the simplest example of promises usage looks like that:

var method1 = (addings = '') => {
  return new Promise(resolve => {
    console.log('method1' + addings)
    resolve(addings + '_adding1');
  });
}
var method2 = (addings = '') => {
  return new Promise(resolve => {
    console.log('method2' + addings)
    resolve(addings + '_adding2');
  });
}

method1().then(method2).then(method1).then(method2);
// result:
// method1            
// method2_adding1    
// method1_adding1_adding2
// method2_adding1_adding2_adding1

That's basic of basics. Having it, you can experiment with rejects:

var method1 = (addings = '*') => {
  return new Promise((resolve, reject) => {
    console.log('method1' + addings)
    resolve(addings + '_adding1');
  });
}
var method2 = (addings = '*') => {
  return new Promise((resolve, reject) => {
    console.log('method2' + addings)
    reject();
  });
}
var errorMethod = () => {
  console.log('errorMethod')
}
method1()
.then(method2, errorMethod)
.then(method1, errorMethod)
.then(method2, errorMethod)
.then(method1, errorMethod)
.then(method2, errorMethod);
// result:
// method1*           
// method2*_adding1
// errorMethod
// method2*
// errorMethod
// method2*

As we can see, in case of failure error function is fired (which is always the second argument of then) and then next function in chain is fired with no given argument.

For advanced knowledge I invite you here.