Promise

一、promise的简略应用

new Promise((resolve, reject) => {    resolve("ok")}).then(data => {    console.log(data) //OK}, error => {    console.log(error)})
//简化下let promise = new Promise(executor)promise.then(onFulfilled, onRejected)
须要留神的是
  • executor是一个会被立刻执行的回调函数, 该函数带有两个参数,resolve reject
  • 如果executor中调用了resolve(value) ,那么这个value则会被传给onFulfilled, 如第一个例子中console.log(data) 输入为ok
  • 如果executor中调用了reject(value) ,那么这个value则会被传给onRejected,作为onRejected的实参
  • 还有一点须要留神的是,promise是带有状态的,开始默认为pending,当调用resolve后,状态变更为fulFilled,当调用reject后,状态变更为rejected。当状态从pending变更为fulFilled / reject后,状态不可再扭转

二、Promise 的高级实现

让咱们持续带着第一个用例 来做个promise的高级实现
new Promise((resolve, reject) => {    resolve("ok")}).then(data => {    console.log(data) //OK}, error => {    console.log(error)})
// 咱们带着例子逐行实现// let executor = (resolve, reject) => { resolve("ok") }// new Promise(executor)class Promise {    constructor(executor){        this.status = "pending" //状态默认为期待态        //executor = (resolve, reject) => { resolve("ok") }        //传入的executor是一个带有两个参数的函数,        //并且参数resolve和reject都是可调用的函数        //所以咱们应该先申明这两个函数 而后当成实参传入 executor        const resolve = (value) => {                    }        const reject = (error) => {                    }        executor(resolve,reject)    }    }
// let executor = (resolve, reject) => { resolve("ok") }// new Promise(executor)class Promise {    constructor(executor){        this.status = "penging"        this.resValue = null        this.rejValue = null        // executor = (resolve, reject) => { resolve("ok") }        const resolve = (value) => {            // 如 resolve("ok") 中传入的"ok"             // 须要在前面代码的then的onFulilled中拿,故须要存储这个 value             this.resValue = value            // 并且调用resolve后,状态更改为fulfilled            if(this.status === "pending"){                this.status = "fulfilled"            }        }        const reject = (error) => {            this.rejValue = error            if(this.status === "pending"){                this.status = "rejected"            }        }        executor(resolve,reject)    }    }
// let promise = new Promise(executor)// promise.then(onFulfilled, onRejected)// 能够得出 promise 须要一个 then 办法class Promise {    constructor(executor){        // 如上...    }    then(onFulfilled, onRejected){        //调用then办法的时候,要判断是以后状态是胜利还是失败        if(this.status === "fulfilled"){            //如果以后是胜利态            onFulfilled(this.value)        }        if(this.status === "rejected"){            //如果以后是失败态            onRejected(this.error)        }    }}
这样算是根本实现了promise 的高级性能,然而当new promise(executor)传入的executor为异步函数的时候,就会呈现问题。如下:
new Promise((resolve,reject)=>{    setTimeout(()=>{       resolve("ok")     },0)}).then(data => {    console.log(data) //不会输入ok})
// 其起因是:当 executor为异步函数传入new Promise`时// 尽管立刻调用了executor,然而其为异步函数,会被推入微工作,不会马上执行// 所以上面这个resolve 不会马上执行,会先执行宏工作的 then 办法// 所以在执行then 办法的时候,promise的状态依然为 pendingclass Promise {    constructor(executor){        // executor = setTimeout(()=>{resolve("ok")},0)        const resolve = (value) => {            // ** 2. 后执行            this.value = value            if(status === "pending"){                this.status = "fulfilled"            }        }        // ...        executor(resolve,reject)    }    then(onFulfilled, onRejected){        // ** 1. 先执行        if(this.status === "fulfilled"){            onFulfilled(this.value)        }        // ...    } }

Promise 的高级实现之异步改良

当初的问题是, 在传入异步函数的时候,咱们执行到then办法的时候, 状态还是为pending,所以无奈执行到onFulfilled。咱们又须要在executor 中调用了resolve后执行 onFulfilled。所以很天然的想到了应用公布订阅模式来解决。即在then中判断到以后为期待态时(那executor肯定是异步函数), 将onFulfilledonRejected存起来, 在executor中执行到resolve后 执行onFulfilled。 上面是代码实现:
class Promise {    constructor(executor){        this.status = "pending"        //onFulfilled汇合        this.onFulfilledCallbacks = [ ]        //onRejected汇合        this.onRejectedCallbacks = [ ]                const resolve = (value) => {            this.resValue = value            if(status === "pending"){                this.status = "fulfilled"                // 公布                this.onFulfilledCallbacks.forEach(callback => {                    callback(this.value)                })            }        }        const reject = (error) => {            this.rejValue = error            if(status === "pending"){                this.status = "rejected"                this.onRejectedCallbacks.forEach(callback => {                    callback(this.error)                })            }        }        executor(resolve,reject)    }    then(onFulfilled, onRejected){        // 同步代码不变,减少异步状况代码        if(this.status === "fulfilled"){            onFulfilled(this.value)        }        if(this.status === "rejected"){            onRejected(this.error)        }        // 新增代码        if(this.status === "pending"){            // 曾经到then了,status的状态还没有扭转。            // 阐明 executor 中为异步函数            // 订阅            this.onFulfilledCallbacks.push((data)=>{                //切片                onFulfilled(data)            })            this.onRejectedCallbacks.push((error)=>{                onRejected(error)            })        }            }}
以上就是promise 的高级实现,promise的外围在于他们链式调用。咱们在下一章具体介绍

三、理解promise的链式调用

    new Promise((resolve,reject) => {        resolve("hello")    }).then(data => {        console.log(data) //hello        return "world"    }).then(data => {        console.log(data) //world    })
如果在then 中return一个简略值(非promise),那么将在下一个 then 中的onFulfilled取到这个值。
    new Promise((resolve,reject) => {        resolve("hello")    }).then(data => {        throw new Error()    }).then(data => {        console.log(data)     },error => {        console.log(error) // Error    })
如果在then中抛出异样,那么将会在下一个then的onRejected拿到这个异样。
    let promise1 = new Promise((resolve,reject) => {        resolve("hello")    }).then(data => {        return data    })        console.log(promise1) // Promise{<fulfilled>: "hello"}    // 能够看得出来: 在then办法中,会返回一个promise对象    // 因为promise的状态不可二次扭转, 所以返回的应该是一个新的promise对象

四、测试案例剖析

在实现promise的链式调用前, 首先要有个测试案例:

let promise1 = new Promise((resolve, reject) => {    setTimeout(() => {        resolve("the message is ")    }, 0);})
let promise2 = promise1.then(data => {    let interPromise = new Promise((resolve,reject) => {        setTimeout(() => {            resolve(data + "that today is a happy day")        }, 0);    })    return interPromise}, null)
我感觉有必要先剖析下这个 promise2
  • 1.首先咱们晓得这个promise1.then()肯定是返回一个新的promise,而且是一个带着实现或完结态的promise
  • 2.所以在then的外部生成一个promise,并且在外部实现了这个promiseresolve(data),而且这个data来之外部的interPromiseresolve()
  • 3.再看下这个interPromise, 他要想把外部的resolve(data + "that today is a happy day")里的数据传给下层thenpromise,那么只能是隐性的调用interPromisethen,并且在这个then中, 调用下层promiseresolve
  • 这是promise中的最难点,如果没看懂,能够多看几遍,糊涂的话能够先看上面的代码实现,再回过头来看这段剖析
let promise3 = promise2.then(data => {    console.log(data) // expect: the message is that today is a happy day})

六、promise的链式调用

该案例为了不便浏览和了解,就实现了最难的性能,并且省略了异样捕捉等内容。
// constructor不变,只对then办法进行了批改class Promise {    constructor(executor) {        this.status = "pending"        this.resValue = null        this.rejValue = null        this.onfulfilledCallbacks = []        this.onrejectedCallbacks = []        const resolve = (value) => {            this.resValue = value            if (this.status === "pending") {                this.status = "fulfilled"                this.onfulfilledCallbacks.forEach(callback => {                    callback(this.resValue)                })            }        }        const reject = (error) => {            this.rejValue = value            if (this.status === "pending") {                this.status = "rejected"                this.onrejectedCallbacks.forEach(callback => {                    callback(this.rejValue)                })            }        }        executor(resolve, reject)    }    then(onFulfilled, onRejected) {        // onFulfilled = data => new Promise(...)        //then 办法返回promise2        const promise2 = new Promise( (resolve2,reject2) => {            if (this.status === "pending") {                //async                 //这里须要一个实现一个异步                //因为在resolvePromise中须要 实现初始化的promise2                setTimeout(()=>{                    this.onfulfilledCallbacks.push(data => {                        //代入案例来看                        //这个x = interPromise                        let x = onFulfilled(data)                        //而后判断这个x 是否是一个 promise                        resolvePromise(x, resolve2, reject2)                    })                                        this.onrejectedCallbacks.push(error => {                        // 类比下面进行批改,这里不做批改                        onRejected(error)                    })                 },0)            }            // 上面状况和下面同理,我不做批改            if (this.status === "fulfilled") {                onFulfilled(this.resValue)            }            if (this.status === "rejected") {                onRejected(this.rejValue)            }                    })        return promise2    }}function resolvePromise(x, resolve2, reject2){    // 源码中有许多判断的异样捕捉,这里就实现最外围的代码    if((typeof x === "object" && typeof x !== "null")|| typeof x === "function"){        // x is a object or function        let then = x.then        if(typeof then === "function"){            // 在这里调用interPromise的then             // 并且调用下层promise的resolve            then.call(x,data => resolve2(data),null)            // x is a promise            // for example: x = new promise((resolve,reject) => {resolve("ok")})        }    }}