Handwritten Promise (native Promise analysis V -- encapsulated by resolve, reject and other methods)

Preface: before that, we have successively encapsulated Promise, then and all, and explained the mechanism and packaging process. Now, we will go through the remaining simpler methods.

1. race()

This method is similar to the all method. The passed in parameter is also an array composed of Promise, but its result analysis is relatively simple. There is no need to think too much. The returned value is also a Promise object. Since the returned Promise object is a Promise object, there is a chain call, so it needs to be encapsulated twice, and the then method needs to be called internally, The result mechanism is as follows: what is returned is a Promise object. The value of the object is the value after the execution of the first Promise in the incoming Promises, and its state is also the state of the Promise. Is it much simpler than the all method? In this case, the encapsulated result is:

// Add race method
Promise.race = function(promises) {
    return new Promise((resolve , reject) => {
        for(let i = 0 ; i < promises.length ; i++) {
            promises[i].then(v => {
                resolve(v)
            } , r => {
                reject(r)
            })
        }
    })
}

The next two methods are also relatively simple (resolve(), reject()), but they are also related to a little key issues. They are similar to the race method we explained earlier.

2. resolve()

The return value and of this method is also a Promise object, and the returned result needs to be distinguished according to the passed in value

(1) : the value passed in is the value of a non Promise object. The final result returned by the method is a Promise in success status, and its value is the value passed in

(2) : the incoming Promise object is the Promise object, and the result returned by the final method should be judged according to the execution result of the incoming Promise object, which is consistent with the execution of the incoming Promise. The incoming Promise is failure, the method returns the failed Promise, the incoming success, and the returned success Promise. All values are the values of the incoming Promise

(3) : throw an exception, which is caught by the then method

So we get:

// Add resolve method
Promise.resolve = function(value) {
    return new Promise((resolve , reject) => {
        if(value instanceof Promise) {
            value.then(v => {
                resolve(v)
            } , r => {
                reject(r)
            })
        } else {
            // The passed in parameter is not a promise object. The direct modification status is success, and the value is the passed in value
            resolve(value)
        }
    })
}

3. reject()

You may think that the reject method is the same as the resolve method. In fact, the reject method is not. Although the return method is also a Promise object, it does not have chain calls, so it does not need secondary encapsulation, and naturally does not need to make too many judgments:

// Add reject method
Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
        reject(reason)
    })
}

The above is the encapsulation of the remaining three methods.

Next, let's do a small optimization of the then method again. Let's take a look at a scenario. Now, the difference between the encapsulated then method and the official library:

Scenario:

        let p1 = new Promise((resolve , rejeve) => {
            resolve("OK")
            console.log(111)
        })

        p1.then(value => {
            console.log(222)
        },reason => {

        })

        console.log(333)

Official results:

Our encapsulated results:

The result is obvious. Why? Well, this will come to the original topic, asynchronous call. We carefully analyze this code. In the official library, the code in Promise is executed first, 111 is output, and a successful callback is called. Right, the code goes down. Because it is an asynchronous call, the code will go down first, synchronous call output 333, and finally execute P1 asynchronously The then () method executes a successful callback and finally outputs 222. However, we did not change this detail. The core code is this:

// Judge the Promise state of the current instance object and call the corresponding function according to the state
if (this.PromiseState === "fulfilled" || this.PromiseState === "resolved") {
     callback(onResolved)
}
if (this.PromiseState === "rejected") {
     callback(onRejected)
}

We execute directly synchronously, so we have to change this paragraph into the amount of asynchronous call. Very simple, just add a timer, just like this (because the timer is asynchronous call, we don't need to define the time of asynchronous call, just leave it blank):

// Judge the Promise state of the current instance object and call the corresponding function according to the state
if (this.PromiseState === "fulfilled" || this.PromiseState === "resolved") {
      setTimeout(() => {
          callback(onResolved)
      })
}
if (this.PromiseState === "rejected") {
      setTimeout(() => {
          callback(onRejected)
      })
}

See the results after debugging again:

So we can optimize it.

So far, our handwritten Promise has been completely completed. Later, I will give a complete Promise and class encapsulated Promise source code, and list some key problems of Promise, as well as some key problems of using Promise. They are also mentioned in the process of encapsulation. Then I will make a summary. Please look forward to it

 

 

Keywords: Javascript Front-end ECMAScript

Added by ghostrider1337 on Sun, 09 Jan 2022 05:53:35 +0200