24

I just implemented my first function that returns a promise based on another promise in AngularJS, and it worked. But before I decided to just do it, I spent 2 hours reading and trying to understand the concepts behind promises. I thought if I could write a simple piece of code that simulated how promises worked, I would then be able to conceptually understand it instead of being able to use it without really knowing how it works. I couldn't write that code.

So, could someone please illustrate in vanilla JavaScript how promises work?

M.K. Safi
  • 6,560
  • 10
  • 40
  • 58
  • 2
    Just to clarify for your expectations... promises are something you implement, and not a language construct in vanilla JavaScript. Check this out: http://www.benlesh.com/2012/09/javascript-promises-promises.html – Brad Aug 24 '13 at 19:02
  • 6
    There is no reason this question should have been closed as too broad. It's a very clear and specific question. – Brad Aug 25 '13 at 15:02
  • Since this still shows up near the top of the SO search results for "how do promises work": vanilla JavaScript has had native promise implementations in all major browsers since 2015. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – Dragonfang Mar 25 '22 at 05:20

4 Answers4

33

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.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • I think this answer can be improved. – Ben Aston Apr 27 '20 at 17:50
  • This doesn't capture [what a promise is](https://stackoverflow.com/a/22562045/1048572) at all – Bergi Nov 05 '21 at 01:06
  • @Bergi: That wasn't the question. I answered this question. not some other question. – Guffa Nov 10 '21 at 11:48
  • @Guffa OP is "*trying to understand the concepts behind promises*", but the implementation in this answer is lacking some key parts in my opinion – Bergi Nov 10 '21 at 13:04
  • @Bergi: That's not what the OP asked for. The OP asked for "a simple piece of code that simulated how promises worked". That's what I put in the answer. If I would have added everything that most implementations of a promise contains, it would have been much more complicated, and harder to understand. As the OP was not trying to understand all aspects of promises, but the core operations, that is what I put in the answer. Again, I answered the question, not any other question that you want to make it into. – Guffa Nov 13 '21 at 19:40
  • @Guffa [The core operation of promises is `.then()`](https://promisesaplus.com), which is missing in your answer. – Bergi Nov 13 '21 at 19:42
  • @Guffa The core functionality, promise chaining, is missing in your `done(f)` method. The object in your answer is a fire-once event with a single listener, literally an awaitable boolean flag. That's not a JS promise. – Bergi Nov 13 '21 at 21:50
  • @Bergi: What is your problem? When I explained that you were wrong in your claim, you move the goal posts to find something else that you think is wrong. If the answer doesn't fulfil what you want to read into the question, that is not a problem with the answer. – Guffa Nov 14 '21 at 19:12
  • @Guffa I'm not moving the goal post. You said yourself that you tried to put the core operations of promises in your answer, we agree that that was the goal. I (and the promises spec) just disagree with your choice (and naming) of those operations. – Bergi Nov 14 '21 at 19:41
3

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.
IRSHAD
  • 2,855
  • 30
  • 39
1

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.

Karol Selak
  • 4,248
  • 6
  • 35
  • 65
0

please check this simple promise code. this will help you to better understand of promise functionality.

A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that it’s not resolved. A promise may be in one of 3 possible states: fulfilled, rejected, or pending. Promise users can attach callbacks to handle the fulfilled value or the reason for rejection.

let myPromise = new Promise((resolve, reject)=>{
  if(2==2){
    resolve("resolved")
  }else{
    reject("rejected")
  }
});

myPromise.then((message)=>{
  document.write(`the promise is ${message}`)
}).catch((message)=>{
  document.write(`the promise is ${message}`)
})

check this out

Community
  • 1
  • 1