Promise is a concept that comes up often in applications and interviews, so it’s important to master its basic usage. The follow-up will output Promise related handwriting implementation, so we must master its method parameters and return value, this article according to ruan Yifeng ES6 on the Promise to sort out!

Theoretical introduction

Promise: Translates as “Promise”. Syntactically, it is an object, a constructor, used to generate instances.

Promise has two features:

  1. The state of an object is unaffected; only the result of an asynchronous operation can change its state.
  2. Once the state changes, it does not change again. The state can only change once.

When it comes to Promise states, he has three:

  1. Pending: Pending
  2. This is a big pity
  3. Failed: Rejected

Since the state can only change once, there are only two ways to change:

  1. pending ->fulfilled
  2. pending->rejected

As soon as any of these things happen the state is fixed and will not change again, it will remain the same and we call this state resolved.

Disadvantages of Promises:

  1. You can’t cancel a Promise, it’s executed after it’s created, and you can’t cancel it halfway through
  2. If you do not set the callback function, errors that occur within a Promise will not be reflected externally. Try… Error caught in catch(err){}
  3. I can’t tell which state I’m in when I’m in a pending state

Basic usage

Analyze usage, mainly from the input parameter and return value.

The Promise object, as a constructor, takes a function as an argument, resolve and reject. These two parameters are function types that are provided by the javascript engine and don’t need to be deployed themselves to change the state of the Promise. Promises are implemented as soon as they are created

Resolve: Invoked when the operation succeeds. This is a pity; this is a pity; this is a pity.

Reject: Called when the operation fails. Change the status from “failed “->” failed”, i.e. pending-> Rejected;

In general, a call to resolve or reject does not block the execution of subsequent code, but by design subsequent code should be executed in. Then, so it is best to precede resolve or reject with a return statement.

Const Promise = new Promise(function(resolve,reject){resolve(value)}else{ reject(reason) } })Copy the code

Promise.prototype.then

Input parameter :(handler in success state, handler in failure state)

** Return value :** New Promise instance.

Once an instance of a Promise is generated, you can use the then method to specify callbacks for the “complete” and “failed” states, respectively, both of which take the value passed from the Promise object as an argument. The then method returns a new Promise instance.

Promise. Then (function(value){// If resolve is a normal value, then it is a normal value. // If promise is another instance, then it is a normal value. Things would be different, see below},function(reason){// a failed handler //reject generally passes an instance of an Error object});Copy the code

As mentioned above, what happens if the argument passed to THEN when Resolve is another Promise instance?

const p1 = new Promise(function (resolve, reject) {    
    setTimeout(() => reject(new Error('fail')), 3000)
})
const p2 = new Promise(function (resolve, reject) {    
    setTimeout(() => resolve(p1), 1000)
})
p2.then(    
    result => console.log('success',result),
    reason => console.log('failed',reason)
)
Copy the code

Yes, it printed failed Error: Fail! Did you get it right? If the resolve method returns another Promise instance, p1, then p1’s state is passed to P2, meaning that P1’s state determines P2’s state. It is important to note that this does not happen if P2 executes reject and returns another Promise instance.

Because the then method still returns a Promise instance, then can be called chained. The result of the previous THEN is passed as an argument to the callback function of the next THEN. If the previous THEN returns the same Promise object, the next THEN will wait for its state to change and decide whether to execute the Resolved or Rejected callback based on the result of its state.

Promise.prototype.catch

Input parameter :(functions that handle errors)

** Return value: ** New Promise instance

**Promise throws an error or calls reject internally.

“Inside promises eat mistakes” is what we mentioned above. Mistakes that happen inside promises don’t reflect on the outside. The logic inside the Promise if something goes wrong, the logic outside the Promise will continue to execute and not exit the process. And Promise errors are not handled by try/catch. If you want to handle errors that occur in promises, the recommended thing to do is.catch.

Errors in the Promise object are “bubbling” and are passed backwards until they are caught.

Promise.prototype.finally

** Input parameter: ** None

** Return value: ** original value

No matter what the state of the Promise is, it is executed.

Promise.all

Input parameter :([p1,p2,p3]), takes an Iterator interface as an argument, usually an array, and each member returned must be a Promise instance. If not, call promise.resolve () first to turn the argument into a Promise instance.

** Return value: ** New PROMISE instance

const p = Promise.all([p1,p2,p3])
Copy the code

The state of p is determined by the array of parameters passed in, in two cases:

  1. The states of all instances in the array will become a pity, and the state of P will become a pity. P’s callback function then takes an array of the return values of all instances. One caveat here is that if the instance as a parameter defines its own catch method, the promise.all catch method will not be raised even if the instance is rejected. Because after a catch is defined, this method also returns a new Promise instance that will be in the Resolved state after the accept.
  2. If there is an instance in the array whose state changes to Rejected, then p’s state changes to Rejected. P’s then callback accepts the return value of the first reject instance.

Promise.race

Inputs :([p1,p2,p3]) same as promise.all

** Return value: ** New Promise instance

const p = Promise.race([p1,p2,p3])
Copy the code

The state of p changes as long as one of the instances in the parameter returns state first. The return value of the first changed Promise instance is passed to THE p callback function then.

Promise.allSettled

Inputs :([p1,p2,p3]) same as promise.all

** Return value: ** New Promise instance

const p = Promise.allSettle([p1,p2,p3])
Copy the code

The state of P will change only after all the instances in the parameter return results, whether they are successful or not, and the state will always be fulfilled. The p callback then takes an array in which each member is an object. Each object has a status attribute whose value can only be the string ‘depressing’ or the string ‘Rejected’. Someday, the object has the value attribute; someday, the object has the reason attribute, which corresponds to the return values of the two states, respectively.

Promise.allsettled is useful for situations where you only care about whether all instances are finished and not the result of execution.

Promise.any

Inputs :([p1,p2,p3]) same as promise.all

** Return value: ** New Promise instance

const p = Promise.any([p1,p2,p3])
Copy the code

As long as one instance becomes a depressing state, then the state of P will become a depressing state.

If all instances become the Rejected state, then p’s state becomes the Rejected state.

Promise.any throws an AggregateError instance.

Promise.resolve

** input: ** is divided into four cases

  1. No arguments: Returns an Resolved Promise object directly
  2. The argument is an instance of Promise: return in place without making any changes
  3. The argument is an object with a THEN method: the object is turned into a Promise object, and the THEN method is executed immediately. The state of the Promise object after the run is determined by the result of the execution in the then method. If a Promise is specified to run resolve or Reject, the Promise state changes to the specified state; otherwise, the Promise state remains pending.
  4. If the argument is another object or not: returns a Promise object with a resolve state. The parameters passed in are passed as arguments to the Promise object’s callback. Then.

Promise.reject

** Entry parameters: ** not limited

** Returns a new Promise instance whose state is Rejected

The promise.reject () argument is returned directly as a. Then value.