1. Immediate execution of Promise

var p = new Promise(function(resolve, reject){
  console.log("create a promise");
  resolve("success");
});

console.log("after new Promise");

p.then(function(value){
  console.log(value);
});
Copy the code

Console output:

"create a promise"
"after new Promise"
"success"
Copy the code

A Promise object represents an event that will happen in the future, but when a (new) Promise is created, the function passed in as a Promise argument is executed immediately, except that the code executed can be asynchronous. Some may think that the function received by the Promise is executed only when the Promise object calls the THEN method. This is incorrect. Therefore, the code “create a promise” is printed before “After new Promise”.

2. I Promise

var p1 = new Promise(function(resolve,reject){
  resolve(1);
});
var p2 = new Promise(function(resolve,reject){
  setTimeout(function(){
    resolve(2);  
  }, 500);      
});
var p3 = new Promise(function(resolve,reject){
  setTimeout(function(){
    reject(3);  
  }, 500);      
});

console.log(p1);
console.log(p2);
console.log(p3);
setTimeout(function(){
  console.log(p2);
}, 1000);
setTimeout(function(){
  console.log(p3);
}, 1000);

p1.then(function(value){
  console.log(value);
});
p2.then(function(value){
  console.log(value);
});
p3.catch(function(err){
  console.log(err);
});
Copy the code

Console output:

Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
1
2
3
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3}
Copy the code

The internal implementation of a Promise is a state machine. There are three states: pending, resolved, and rejected. When the Promise has just been created, it is in the pending state. When the function parameter in the Promise is resolved, the Promise changes from pending to Resolved. If a Promise is rejected instead of resolve, the Promise will change from its pending state to its Rejected state.

When P2 and P3 were created, both promises output by the console were in the pending state, but why was P1 in the resolved state? The resolve method is called as soon as the Promise has been created and the output that follows shows that P1 is in the resolved state. We use two setTimeout functions to output the status of P2 and P3 again after 1 second delay. At this time, P2 and P3 have been executed and become resolved and REJECTED respectively.

3. The irreversibility of the Promise state

var p1 = new Promise(function(resolve, reject){
  resolve("success1");
  resolve("success2");
});

var p2 = new Promise(function(resolve, reject){
  resolve("success");
  reject("reject");
});

p1.then(function(value){
  console.log(value);
});

p2.then(function(value){
  console.log(value);
});
Copy the code

Console output:

"success1"
"success"
Copy the code

Once the Promise state is resolved or Rejected, the Promise state and value are fixed, no matter how much you call resolve or reject. Therefore, resolve(“success2”) in P1 cannot change the value of P1 to Success2, and reject(“reject”) in P2 cannot change the state of P2 from Resolved to Rejected.

4. Chained calls

var p = new Promise(function(resolve, reject){
  resolve(1);
});
p.then(function(value){// The first onethen
  console.log(value);
  return value*2;
}).then(function(value){// The secondthen
  console.log(value);
}).then(function(value){// The thirdthen
  console.log(value);
  return Promise.resolve('resolve'); 
}).then(function(value){// The fourththen
  console.log(value);
  return Promise.reject('reject');
}).then(function(value){// The fifththen
  console.log('resolve: '+ value);
}, function(err){
  console.log('reject: ' + err);
})
Copy the code

Console output:

1
2
undefined
"resolve"
"reject: reject"
Copy the code

The THEN method of the Promise object returns a new Promise object, so the THEN method can be called chained. The then method takes two functions as arguments, the first a callback if the Promise succeeds, and the second a callback if the Promise fails. Only one of the two functions will be called, and the return value of the function will be used to create the Promise object returned by the THEN. The return value of these two arguments can be one of three:

  • returnA synchronous value, orundefined(The default value is undefined when no valid value is returned),thenMethod returns a Promise object in the resolved state. The value of the Promise object is the returned value.
  • returnAnother Promise,thenMethod will return a new Promise object based on the Promise’s state and value.
  • throwA synchronization exception,thenMethod returns a Promise in the rejected state, the value of which is the exception.

Based on the analysis above, the first THEN in the code returns a Promise object with the value 2 (1*2) in the resolved state, so the second THEN output is 2. The second THEN returns no value, so default undefined is returned, and the third THEN outputs undefined. The third then returns a Promise that is in the Resolved state and the fourth THEN returns a Promise that is in the Rejected state, which is handled by the successful callback function in the fourth THEN and the failed callback function in the fifth THEN.

5.Promise then() callback asynchronism

var p = new Promise(function(resolve, reject){
  resolve("success");
});

p.then(function(value){
  console.log(value);
});

console.log("which one is called first ?");
Copy the code

Console output:

"which one is called first ?"
"success"
Copy the code

The function arguments received by the Promise are executed synchronously, but the callback in the THEN method is executed asynchronously, so “SUCCESS” is printed later.

6. Exceptions in Promise

var p1 = new Promise( function(resolve,reject){
  foo.bar();
  resolve( 1 );	  
});

p1.then(
  function(value){
    console.log('p1 then value: ' + value);
  },
  function(err){
    console.log('p1 then err: ' + err);
  }
).then(
  function(value){
    console.log('p1 then then value: '+value);
  },
  function(err){
    console.log('p1 then then err: '+ err); }); var p2 = new Promise(function(resolve,reject){
  resolve( 2 );	
});

p2.then(
  function(value){
    console.log('p2 then value: ' + value);
    foo.bar();
  }, 
  function(err){
    console.log('p2 then err: ' + err);
  }
).then(
  function(value){
    console.log('p2 then then value: ' + value);
  },
  function(err){
    console.log('p2 then then err: ' + err);
    return 1;
  }
).then(
  function(value){
    console.log('p2 then then then value: ' + value);
  },
  function(err){
    console.log('p2 then then then err: '+ err); });Copy the code

Console output:

p1 then err: ReferenceError: foo is not defined
p2 then value: 2
p1 then then value: undefined
p2 then then err: ReferenceError: foo is not defined
p2 then then then value: 1
Copy the code

Exceptions in a Promise are handled by the second callback function in the THEN parameter (the callback that the Promise failed to execute), and the exception message is used as the value of the Promise. Once the exception is handled, subsequent Promise objects returned by then are restored to normal and handled by the callback function that the Promise executed successfully. Also, note that the p1 and P2 multilevel THEN callbacks are executed alternately due to the asynchrony of the Promise THEN callbacks.

7.Promise.resolve()

var p1 = Promise.resolve( 1 );
var p2 = Promise.resolve( p1 );
var p3 = new Promise(function(resolve, reject){
  resolve(1);
});
var p4 = new Promise(function(resolve, reject){
  resolve(p1);
});

console.log(p1 === p2); 
console.log(p1 === p3);
console.log(p1 === p4);
console.log(p3 === p4);

p4.then(function(value){
  console.log('p4=' + value);
});

p2.then(function(value){
  console.log('p2=' + value);
})

p1.then(function(value){
  console.log('p1=' + value);
})
Copy the code

Console output:

true
false
false
false
p2=1
p1=1
p4=1
Copy the code

Promise.resolve(…) You can accept either a value or a Promise object as an argument. When the argument is a normal value, it returns a Promise object in the resolved state whose value is this parameter. When the argument is a Promise object, it returns the Promise argument directly. So p1 === p2. But the Promise object created by the new method is a new object, so the next three comparisons are false. Also, why is P4’s THEN called first, but output last on the console? Because the argument received in P4’s resolve is a Promise object p1, resolve “unboxes” P1 to get the status and value of P1, but this process is asynchronous, see the next section.

8.resolve vs reject

var p1 = new Promise(function(resolve, reject){
  resolve(Promise.resolve('resolve'));
});

var p2 = new Promise(function(resolve, reject){
  resolve(Promise.reject('reject'));
});

var p3 = new Promise(function(resolve, reject){
  reject(Promise.resolve('resolve'));
});

p1.then(
  function fulfilled(value){
    console.log('fulfilled: ' + value);
  }, 
  function rejected(err){
    console.log('rejected: '+ err); }); p2.then(function fulfilled(value){
    console.log('fulfilled: ' + value);
  }, 
  function rejected(err){
    console.log('rejected: '+ err); }); p3.then(function fulfilled(value){
    console.log('fulfilled: ' + value);
  }, 
  function rejected(err){
    console.log('rejected: '+ err); });Copy the code

Console output:

p3 rejected: [object Promise]
p1 fulfilled: resolve
p2 rejected: reject
Copy the code

The first argument, resolve, in the Promise callback, “unboxes” the Promise. When the argument to resolve is a Promise object, resolve “unboxes” the Promise object’s state and value, but the process is asynchronous. P1: the state of the Promise object is resolved, so the fulfilled callback is fulfilled. P2 after “unpacking”, we get the Promise object’s state is rejected, so the rejected callback is executed. However, the second argument in the Promise callback, reject, does not have the ability to “unbox” it. The reject argument is passed directly to the Rejected callback in the THEN method. Thus, even if P3 rejects a Promise in the resolved state, the then method is still rejected and the argument is the promised object that was received.


Welcome to pay attention to my public number: senior cadres of the front end, get 21 front end selected books!