自定义Promise之then方法的实现(下)

2. then方法的实现(下)

根据原生Promise可知,在执行then方法后会返回一个新的Promise实例对象,而实例对象的状态取决于以下几点:

  • then方法中回调函数返回了一个非Promise对象,则该新的Promise实例对象状态为fulfilled
  • then方法中回调函数返回了一个Promise对象,则该新的Promise实例对象状态为该Promise对象的状态
  • then方法中回调函数中抛出异常,则该新的Promise实例对象状态为rejected

2.1 同步下then方法返回结果的实现

2.1.1 then方法的返回值是新的Promise对象

/*
  为 promise 指定成功/失败的回调函数
  函数的返回值是一个新的 promise 对象
*/
Promise.prototype.then = function (onResolved, onRejected) {
    // 返回一个新的promise对象
    return new Promise((resolve, reject) => {
        // 判断实例的状态
        if(this.PromiseState === 'fulfilled') {
            onResolved(this.PromiseResult)
        }

        if(this.PromiseState === 'rejected') {
            onRejected(this.PromiseResult)
        }

        if(this.PromiseState === 'pending') {
            // 将回调函数存入callback中
            this.callbacks.push({
                onResolved,
                onRejected
            })
        }
    })
}

2.1.2 判断回调函数返回结果

Promise.prototype.then = function (onResolved, onRejected) {
    // 返回一个新的promise对象
    return new Promise((resolve, reject) => {
        // 判断实例的状态
        if(this.PromiseState === 'fulfilled') {
            // 获取回调函数的执行结果
            let result = onResolved(this.PromiseResult)
            // 判断结果是否为Promise实例
            if(result instanceof Promise) {
                // 根据result的状态去修改返回的新的promise对象状态
                result.then(resolve, reject)
            } else {
                // 结果的对象状态为成功
                resolve(result)
            }
        }

        if(this.PromiseState === 'rejected') {
            // 获取回调函数的执行结果
            let result = onRejected(this.PromiseResult)
            // 判断结果是否为Promise实例
            if(result instanceof Promise) {
                // 根据result的状态去修改返回的新的promise对象状态
                result.then(resolve, reject)
            } else {
                // 结果的对象状态为成功
                resolve(result)
            }
        }

        if(this.PromiseState === 'pending') {
            // 将回调函数存入callback中
            this.callbacks.push({
                onResolved,
                onRejected
            })
        }
    })
}

2.1.3 处理回调函数中抛出异常问题

/*
  为 promise 指定成功/失败的回调函数
  函数的返回值是一个新的 promise 对象
  */
Promise.prototype.then = function (onResolved, onRejected) {
    // 返回一个新的promise对象
    return new Promise((resolve, reject) => {
        // 判断实例的状态
        if(this.PromiseState === 'fulfilled') {
            try {
                // 获取回调函数的执行结果
                let result = onResolved(this.PromiseResult)
                // 判断结果是否为Promise实例
                if(result instanceof Promise) {
                    // 根据result的状态去修改返回的新的promise对象状态
                    result.then(resolve, reject)
                } else {
                    // 结果的对象状态为成功
                    resolve(result)
                }
            } catch (error) {
                // 出现异常,则返回的新的promise对象直接转换为rejected
                reject(error)
            } 
        }

        if(this.PromiseState === 'rejected') {
            try {
                // 获取回调函数的执行结果
                let result = onRejected(this.PromiseResult)
                // 判断结果是否为Promise实例
                if(result instanceof Promise) {
                    // 根据result的状态去修改返回的新的promise对象状态
                    result.then(resolve, reject)
                } else {
                    // 结果的对象状态为成功
                    resolve(result)
                }
            } catch (error) {
                // 出现异常,则返回的新的promise对象直接转换为rejected
                reject(error)
            } 
        }

        if(this.PromiseState === 'pending') {
            // 将回调函数存入callbacks中
            this.callbacks.push({
                onResolved,
                onRejected
            })
        }
    })
}

2.2 异步下then方法返回结果的实现

2.2.1 改造存入callbacks中的函数

异步下,then方法的回调函数是在构造函数中调用的,因此需要对存入callbacks中的函数进行改造

在函数中,需要注意this指向问题

// then方法
// 保存this
const self = this

if(this.PromiseState === 'pending') {
    // 将回调函数存入callback中
    this.callbacks.push({
        onResolved(){
            try {
                // 获取回调函数的执行结果
                let result = onRejected(self.PromiseResult)
                // 判断结果是否为Promise实例
                if(result instanceof Promise) {
                    // 根据result的状态去修改返回的新的promise对象状态
                    result.then(resolve, reject)
                } else {
                    // 结果的对象状态为成功
                    resolve(result)
                }
            } catch (error) {
                // 出现异常,则返回的新的promise对象直接转换为rejected
                reject(error)
            } 
        },
        onRejected(){
            try {
                // 获取回调函数的执行结果
                let result = onRejected(self.PromiseResult)
                // 判断结果是否为Promise实例
                if(result instanceof Promise) {
                    // 根据result的状态去修改返回的新的promise对象状态
                    result.then(resolve, reject)
                } else {
                    // 结果的对象状态为成功
                    resolve(result)
                }
            } catch (error) {
                // 出现异常,则返回的新的promise对象直接转换为rejected
                reject(error)
            } 
        }
    })
}

2.3 then方法的完善和优化

在then方法中,有多个地方使用了大量功能重复的代码,因此可以进行抽取封装优化

/*
  为 promise 指定成功/失败的回调函数
  函数的返回值是一个新的 promise 对象
  */
Promise.prototype.then = function (onResolved, onRejected) {
    // 保存this
    const self = this
    // 返回一个新的promise对象
    return new Promise((resolve, reject) => {
        // 封装通用函数
        function handler(callback) {
            try {
                // 获取回调函数的执行结果
                let result = callback(self.PromiseResult)
                // 判断结果是否为Promise实例
                if(result instanceof Promise) {
                    // 根据result的状态去修改返回的新的promise对象状态
                    result.then(resolve, reject)
                } else {
                    // 结果的对象状态为成功
                    resolve(result)
                }
            } catch (error) {
                // 出现异常,则返回的新的promise对象直接转换为rejected
                reject(error)
            } 
        }

        // 判断实例的状态
        if(this.PromiseState === 'fulfilled') {
            handler(onResolved)
        }

        if(this.PromiseState === 'rejected') {
            handler(onRejected)
        }

        if(this.PromiseState === 'pending') {
            // 将回调函数存入callback中
            this.callbacks.push({
                onResolved(){
                    handler(onResolved)
                },
                onRejected(){
                    handler(onRejected)
                }
            })
        }
    })
}

2.4 then方法异步执行问题

根据原生Promise可知,then方法一定是异步执行,且会被放入微队列中。在执行回调函数时,可以简单的使用定时器来模拟异步执行

// Promise构造函数

// resolve函数,将实例对象的状态转为fulfilled
function resolve(value) {
    // 遍历callbacks,执行其中所有的onResolved回调函数
    setTimeout(()=>{
        self.callbacks.forEach(item => {
            item.onResolved(value)
        })
    })
}

// resolve函数,将实例对象的状态转为rejected
function reject(reason) {
    // 遍历callbacks,执行其中所有的onResolved回调函数
    setTimeout(()=>{
        self.callbacks.forEach(item => {
            item.onRejected(reason)
        })
    })
}

// then方法
// 判断实例的状态
if(this.PromiseState === 'fulfilled') {
    setTimeout(()=>{
        handler(onResolved)
    })
}

if(this.PromiseState === 'rejected') {
    setTimeout(()=>{
        handler(onRejected)
    })
}
暂无评论

发送评论 编辑评论


				
上一篇
下一篇