Home  >  Article  >  Web Front-end  >  In-depth analysis of Promise implementation ideas (code examples)

In-depth analysis of Promise implementation ideas (code examples)

不言
不言forward
2018-11-24 14:09:221896browse

This article brings you an in-depth analysis of Promise implementation ideas (code examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Personal understanding of Promise implementation ideas

I have always felt that although Promise is convenient, its writing method is very strange, and I cannot understand how people who implement Promise think. of.

However, recently I have gained a little personal understanding of the thinking process of implementing Promise, so I will write it down here.

I feel like I still haven’t explained my ideas clearly in this article. Time is tight, so I will treat it as a record. I will express this process more clearly later.

Use case

   var p1 = new Promise2( ( resolve, reject ) => {
            setTimeout( () => {
                resolve( 'hello' )
            }, 1000 )

        } )

        p1.then( res => {
                console.log( res + 'world' )
                return res + 'world'
            } )
            .then( res => {
                console.log( res + 'ziwei' )
                return res + 'ziwei'
            } )

I think implementing a function is similar to encapsulating a component. First, consider the following points:

  • 1 .What is this function used for?

  • 2. What parameters are accepted?

  • 3. What is the return value?

Then combine the examples , and these questions, we get

  • 1.Promise is used for asynchronous process control. In layman's terms, I hope that a certain function will not be executed temporarily. When I want it to be executed, I will resolve it and your function will be executed.

  • 2.Constructor Promise accepts a function. The parameters of the function are resolve, reject, resolve and reject are also functions, which are called by the user. When the user wants the next asynchronous execution, call resolve(0

  • 3. Returns a promise instance. Each promise instance has a then method, and the then method also returns a new promise instance. From this, you can call then in a chain

First implement a Promise (the chain call of then is not implemented)
  • 1. Promise accepts a fn, regardless of other things, what do you think this fn will do internally? You can only is called, so although I don’t know how to do it, first call fn(resolve,reject)

  • 2. Then this resolve and reject are not implemented by users, so they must be developed by Promise or implement, then we need to implement resolve and reject. What are they used for? They must be used to change the state, so defining this.state

  • 3.resolve and reject will also Accept the user's parameters, then we need to cache this parameter with this.value. When the then method is called in the future, it needs to be passed in

  • 4.then accepts successFn and errorFn, this The two are the functions we hope not to execute temporarily. How to prevent them from being executed temporarily? Just declare two arrays, save them first, and call

        class Promise2 {
            constructor( fn ) {
                this.successFnArray = []  // 用来缓存successFn和errorFn
                this.errorFnArray = []
                this.state = 'pendding'
                const resolve = ( res ) => {      // resolve就做2件事情  1: 修改状态 2:调用successFn
                    this.state = 'fulfilled'
                    this.value = res         // this.value用来缓存data数据或者error

                    this.successFnArray.forEach( successFn => {
                        successFn( res )
                    } )
                }
                const reject = ( err ) => {
                    this.state = 'rejected'
                    this.value = err

                    this.errorFnArray.forEach( errorFn => {
                        errorFn( res )
                    } )
                }
                fn( resolve, reject )   // 先调用fn再说
            }

            then( successFn, errorFn ) {
                switch ( this.state ) {
                    case 'fulfilled':
                        successFn( this.value )        // 如果调用了resolve,状态就成了fulfilled,就会执行successFn
                        break
                    case 'rejected':
                        errorFn( this.value )
                        break
                    case 'pendding':
                        this.successFnArray.push( successFn )   // 如果还没调用resolve,状态就是pendding,就先把这些异步函数缓存起来。将来resole时调用
                        this.errorFnArray.push( errorFn )
                }
            }
        }

        var p1 = new Promise2( ( resolve, reject ) => {
            setTimeout( () => {
                resolve( 'hello' )
            }, 1000 )

        } )

        p1.then( res => {
            console.log( res + 'world' )
            return res + 'world'
        } )
## when resolving in the future.

#Implement then chain call

The implementation of then is different from JQ's chain call. JQ returns this after each method call

And Promise specification Requirements, a new Promise object must be returned every time

So you only need to modify the then method.

This part may be confusing, but I want to talk about what is done here first. In fact, there is not much change

What did the previous then do?

  • It is to call successFn or errorFn according to different states. If it is in the pending state, it is cached first. , and will be called when resolving in the future.

What are the changes to the chained then?

  • First of all, then has a return value and returns a promise, while before There is no return value. What is returned is the process of undefined

  • new Promise. In fact, the logic has not changed. The only thing to note is that, for example, when the status is fulfilled, successFn

    # is not called directly.
  • ## Instead, _successFn is called, and this function essentially still calls successFn(), but at the same time, the return value of the call is used as the parameter of resolve, and resolve() is called

Because when successFn When called and the return value is obtained, it means that the function has been executed.

The next asynchronous function needs to be executed, so that the next asynchronous function will also use the return value of successFn(res) as a parameter

       then( successFn, errorFn ) {
                
                return new Promise2( ( resolve, reject ) => {
                    const _successFn = res => {
                        resolve(successFn(res))
                    }
                    const _errorFn = err => {
                        reject(errorFn(err))
                    }
                    
                    switch ( this.state ) {
                        case 'fulfilled':
                        _successFn( this.value )
                            break
                        case 'rejected':
                        _errorFn( this.value )
                            break
                        case 'pendding':
                            this.successFnArray.push( _successFn )
                            this.errorFnArray.push( _errorFn )
                    }
                } )

            }

The above is the detailed content of In-depth analysis of Promise implementation ideas (code examples). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete