Basic use of Promise

const promise = new Promise((resolve, reject) = > {
        try {
            resolve('123')}catch(err) {
            reject('error')
        }
})


promise.then((msg) = > {
    console.log(msg)
})
Copy the code

A simple implementation of class

class myPromise1 {
    // The constructor accepts a function
    constructor(callback) {
        callback(this.resolve, this.reject)
    }

    resolve = (value) = > {}
    reject = (reason) = >{}}Copy the code

Three states

const  stateArr = ['pending'.'fulfilled'.'rejected']

class myPromise2 {
    constructor(callback) {
        this.state = stateArr[0]
        this.value = null
        this.reason = null

        callback(this.resolve, this.reject)
    }

    resolve = (value) = > {
        //
        if(this.state === stateArr[0])
        this.state = stateArr[1]
        this.value = value
    }

    reject = (reason) = > {
        //
        if (this.state === stateArr[0]) {
            this.state = stateArr[2]
            this.reason = reason
        }
    }
}
Copy the code

Then method

// const stateArr = ['pending', 'fulfilled', 'rejected']

class myPromise3 {
    constructor(callback) {
        this.state = stateArr[0]
        this.value = null
        this.reason = null

        callback(this.resolve, this.reject)
    }

    resolve = (value) = > {
        //
        if(this.state === stateArr[0])
        this.state = stateArr[1]
        this.value = value
    }

    reject = (reason) = > {
        //
        if (this.state === stateArr[0]) {
            this.state = stateArr[2]
            this.reason = reason
        }
    }

    then = (onFulfilled, onRejected) = > {
        // Judge ondepressing, onRejected is a function, if not, it will be ignored
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) = > value;
        onRejected = typeof onRejected === 'function' ? onRejected : 
        (reason) = > reason

        // fulFilled
        if(this.state === stateArr[1]) {
            return new myPromise3((resolve, reject) = > {
                try{
                    const result = onFulfilled(this.value)
                    // ondepressing returns a Promise, then is called
                    if (result instanceof myPromise3) {
                        result.then(resolve, reject)
                    } else{
                        resolve(result)
                    }
                } catch(err) {
                    reject(err)
                }
            })
        }

        // rejected
        if (this.state === stateArr[2]) {

            // Then must return a promise
            return new myPromise3((resolve, reject) = > {
                try {
                    const result = onRejected(this.reject)
                    //
                    if (result instanceof myPromise3) {
                        result.then(resolve, reject)
                    } else {
                        resolve(result)
                    }
                } catch(err) {
                    reject(err)
                }
            })
        }

    }
}
Copy the code

Asynchronous request

Currently resolve cannot be executed in context, which causes then to fail

  • Save the method in then and wait for resolve or Reject to execute before calling the method in the just-saved THEN
  • Since more than one THEN method may be executed during this time, a single piece of data is needed to hold these methods

class myPromise4 {
    constructor(callback) {
        this.state = stateArr[0]
        this.value = null
        this.reason = null
        // Add the resolve reject method array
        this.resolveArr = []
        this.rejectArr = []

        callback(this.resolve, this.reject)
    }

    resolve = (value) = > {
        // Check whether the state needs to be pending
        if(this.state === stateArr[0])
        this.state = stateArr[1]
        this.value = value

        this.resolveArr.forEach(fun= > fun(value))
    }

    reject = (reason) = > {
        //
        if (this.state === stateArr[0]) {
            this.state = stateArr[2]
            this.reason = reason

            this.rejectArr.forEach(fun= > fun(reason))
        }
    }

    // Add logic to catch pending state in the then method
    then = (onFulfilled, onRejected) = > {
        // Judge ondepressing, onRejected is a function, if not, it will be ignored
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) = > value;
        onRejected = typeof onRejected === 'function' ? onRejected : 
        (reason) = > reason


        if (this.state === stateArr[0]) {
            return new myPromise4((resolve, reject) = > {
                // Insert successfully
                this.resolveArr.push((value) = > {
                    try {
                        const result = onFulfilled(value)
                        if (result instanceof myPromise4) {
                            result.then(resolve, reject);
                        } else{ resolve(result); }}catch(err) {
                        reject(err)
                    }
                })

                // Insert failed
                this.rejectArr.push((value) = > {
                    try {
                        const result = onRejected(value);
                        if (result instanceof myPromise4) {
                            result.then(resolve, reject);
                        } else{ resolve(result); }}catch(err) {
                        reject(err)
                    }
                })
            })
        }
        // fulFilled
        if(this.state === stateArr[1]) {
            return new myPromise3((resolve, reject) = > {
                try{
                    const result = onFulfilled(this.value)
                    // ondepressing returns a Promise, then is called
                    if (result instanceof myPromise3) {
                        result.then(resolve, reject)
                    } else{
                        resolve(result)
                    }
                } catch(err) {
                    reject(err)
                }
            })
        }

        // rejected
        if (this.state === stateArr[2]) {

            // Then must return a promise
            return new myPromise3((resolve, reject) = > {
                try {
                    const result = onRejected(this.reject)
                    //
                    if (result instanceof myPromise3) {
                        result.then(resolve, reject)
                    } else {
                        resolve(result)
                    }
                } catch(err) {
                    reject(err)
                }
            })
        }

    }
}

Copy the code

test

new myPromise4((resolve, reject) => {
    setTimeout(() => {
        resolve(123);
    }, 2000)
})
.then(msg => {
    console.log(msg);
    return new myPromise4((resolve, reject) => {
        setTimeout(()=> {
            resolve(456)
        }, 2000);
    })
})
.then(msg => {
    console.log(msg);
})
Copy the code