promise

Reference: Zhihu Ruan Yifeng ES6 MDN

I saw a video from geek University earlier, and the teacher talked about the traceability of learning, what is the traceability, is the link of your learning process about a knowledge point. When I learned Promise: First of all, I watched the video for a general understanding, then read the content about this part in the Little Red Book, then read some technical blogs and summarized a blog by myself.

Common interview questions

  • What problem did Promise solve
  • What are the apis used by Promise?
  • Write A Promise that conforms to the Promise/A+ specification
  • What are the flaws in promises, and how can we fix them?

concept

What is a Promise?

A Promise is an object that represents the final completion or failure of an asynchronous operation.

let p=new Promise(()=>{});
setTimeout(console.log,0,p)//Promise<pending>
Copy the code

Three states of Promise

  • Pending
  • Cash out (Resolved)
  • I don’t like it!
  1. Pending is the initial state, from pending to accept or reject, the status of the contract does not change
  2. The status of the contract is not affected by external influences and is private. The Promise object represents an asynchronous operation, and only the result of the asynchronous operation can determine which state is currently in. No other operation can change that state

What problem did Promise solve

Asynchronous behavior is the foundation of JS, and previous implementations have not been ideal. Early JS only supported defining callback functions to indicate asynchronous completion. Concatenating multiple asynchronous operations is a common problem. Deeply nested callback functions (colloquially called “callback hell”) are often required.

Promise solves this problem because it can be invoked chained

  1. Eliminate nested calls: This can be solved by the chained calls of Promise;
  2. Result of merging multiple tasks: promise.all () promise.race ()

– What are the apis used by Promise?

  • Promise.resolve()
  • Promise.reject()
  • Promise.prototype.then()
  • Promise.prototype.catch()
  • Promise.prototype.finally()
  • Promise.all()
  • Promise.race()

The realization of the Promise. The resolve ()

The following two contract instances are actually the same

let p1=new Promise((resolve,reject)=>resolve())

let p2=Promise.resolve()

Default produces a successful promise.

static resolve(data){
    new Promise((resolve,reject)=>resolve(data))
}
Copy the code

It’s important to note that promise.resolve has wait capability. If the argument is a promise, it will wait for the promise to resolve and then execute down, so there is a little processing to do in the resolve method:

The realization of the Promise. Reject ()

The following two contract instances are actually the same

Let p1=new Promise((resolve,reject)=>reject()) let p2= promise.reject () produces a failed Promise by default, promise.reject directly converts the value to the wrong result. Can be called a reason.

static reject(reason){
    new Promise((resolve,reject)=>reject(reason))
}
Copy the code

The realization of the Promise. Prototype. Then

The then method accepts a maximum of two arguments: onResolved and the onRejected handler. Both parameters are optional and are executed when the contract enters the “cash” and “reject” states, respectively

The realization of the Promise. The prototype. The catch

Prototype. then(null,onRejected)

Promise.prototype.catch=function(errCallback){
    return this.then(null,errCallback)
}
Copy the code

The realization of the Promise. Prototype. Finally

Finally means not final, but something that will be done anyway. He cannot detect whether the expiry status is resolved or rejected. He will only appear as the passing of the paternal covenant

Promise.prototype.finally=function(callback){
    return this.then((value)=>{
       return Promise.resolve(callback).then(()=>value)
    },(reason)=>{
        return Promise.reject(callback).then(()=>throw reason)
    })
}
Copy the code

Test it out:

Promise.resolve(456).finally(()=>{
  return new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve(123)
    }, 3000);
  })
}).then(data=>{
  console.log(data,'success')
}).catch(err=>{
  console.log(err,'error')
})
Copy the code

Console waits for 3s and outputs: “456 Success”

Promise. All () and Promise. Race ()

Both of these are methods of combining multiple contract instances into a single contract

Promise.all()

This static method creates appointments that are resolved after a set of appointments has all been resolved. This static method takes an iterable and returns a new date.

let p1 =Promise.all([ Promise.resolve(), Promise.resolve(), Resolve () let p2= promise.all ([1,2]) // empty iterables are equivalent to promise.resolve () let p3= promise.all ([]) Let p4= promise.all ()Copy the code

The composite term is resolved only after each contained term has been resolved

let p=Promise.all([ Promise.resolve(), new Promise( (resolve,reject)=>setTimeout(resolve,1000) ) ]) setTimeout(console.log,0,p) P.teng (()=>setTimeout(console.log,0," Printable successfully "))Copy the code

//Promise // Prints successfully for 1s

If at least one contained term is pending, the composite term is also pending. If an contained term is rejected, the composite term is also rejected. If all terms are successfully resolved, then the resolution values of the composite term are all the arrays containing the resolution values of the term, in iteration group order:

let p=Promise.all([
    Promise.resolve(3),
    Promise.resolve(),
    Promise.resolve(4)
])
p.then((values)=>setTimeout(console.log,0,values));
Copy the code

//[3, undefined, 4]

If the fixed-term contract is rejected, the first fixed-term contract that rejects will use its own reasons as the reason for the refusal of the composite fixed-term contract. Subsequent terms of rejection do not affect the grounds for rejection of the final terms.

Promise.race()

This static method returns a wrapper term that is a mirror image of the first term resolved or rejected in a set of collections. This method takes an iterable and returns a new date.

Promise.race() does not discriminate between resolved or rejected terms. Promise.race() wraps its settlement value or rejection reason for the first settled term, either resolved or rejected, and returns the new term:

let p1=Promise.race([
    Promise.resolve(3)
    ,new Promise((resolve,reject)=>setTimeout(reject,1000))
])
setTimeout(console.log,0,p1)//Promise<resolved>:3
Copy the code

The iteration order determines the order of termination and does not affect the normal rejection operation of the inclusion contract. The synthesized date silently handles all normal reject operations that contain the date.

Write A Promise that conforms to the Promise/A+ specification

I want to summarize this section in a separate blog because it’s too long. Click here to enter directly

What are the flaws in promises, and how can we fix them?

1. The schedule shall be cancelled. 2. The specific implementation of progress tracking shall be updated.