How do promises work in JavaScript?

2019-01-10 21:01发布

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?

3条回答
甜甜的少女心
2楼-- · 2019-01-10 21:37

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.
查看更多
放荡不羁爱自由
3楼-- · 2019-01-10 21:38

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.

查看更多
我命由我不由天
4楼-- · 2019-01-10 21:48

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.

查看更多
登录 后发表回答