js中promise原理及手动基本实现_V4

前言

上一章,我们实现了promise的then方法链式调用,本章节就对原型promise的catch方法进行简单的实现,同时对对象进行一个整体的异常处理优化,以提高对象整体的健壮度。

上一章链接:https://blog.csdn.net/weixin_42344533/article/details/117624450

过程

1、promise对象catch方法实现效果图。

2、实现catch原理:其实就是then方法的语法糖,参数,内部实现最终还是利用了then方法。

3、由于本人的疏忽,造成上一个版本存在一个bug,就是后一个then方法会错误地接收前一个then方法返回的err,造成回调混乱。

4、本版本对上一版本的bug进行了修复,对全局的handlePromise方法进行了修改,多传进来当前对象的status状态,通过判断该状态来决定执行resolve方法还是reject方法。

5、该版本还对promise对象内部进行了异常处理的优化,防止外部函数的错误而造成内部函数执行的失败,同时通过reject把异常抛出。

实现源码myPromise_v4.js:

const RESOLVE = 'resolved'
const REJECT = 'rejected'
const PENDING = 'pending'

const handlePromise = (status, result, newPromise, resolve, reject) => {
    if (result === newPromise) {
        throw new Error('can not return oneself')
    }
    if ((typeof result === "object" && result != null) || typeof result === "function") {
        let lock = false
        try {
            const then = result.then
            if (typeof then === "function") {
                then.call(
                    result,
                    r => {
                        if (lock) return
                        handlePromise(r, newPromise, resolve, reject)
                        lock = true
                    },
                    e => {
                        if (lock) return
                        reject(e)
                        lock = true
                    }
                )
            } else {
                resolve(result)
            }
        } catch (error) {
            reject(error)
        }
    } else if (status === RESOLVE) {
        resolve(result)
    } else {
        reject(result)
    }
}

function selfPromise(exe) {
    this.status = PENDING
    this.result = undefined
    this.reason = undefined
    this.resolveAsyList = []
    this.rejectAsyList = []
    this.init = (exe) => {
        const resolve = (result) => {
            if (this.status === PENDING) {
                this.result = result
                this.status = RESOLVE
                this.resolveAsyList.map(resolveAsy => {
                    resolveAsy()
                })
            }
        }
        const reject = (reason) => {
            if (this.status === PENDING) {
                this.reason = reason
                this.status = REJECT
                this.rejectAsyList.map(rejectAsy => {
                    rejectAsy()
                })
            }
        }
        try {
            exe(resolve, reject);
        } catch (error) {
            reject(error)
        }

    }
    this.init(exe)
    this.then = (onResolve, onReject) => {
        onResolve = typeof onResolve === "function" ? onResolve : (data) => data
        onReject = typeof onReject === "function" ? onReject : (err) => err
        const newPromise = new selfPromise((resolve, reject) => {
            if (this.status === RESOLVE) {
                setTimeout(() => {
                    try {
                        const result = onResolve(this.result)
                        handlePromise(RESOLVE, result, newPromise, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }

                }, 0)
            }
            if (this.status === REJECT) {
                setTimeout(() => {
                    try {
                        const result = onReject(this.reason)
                        handlePromise(REJECT, result, newPromise, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                }, 0)
            }
            if (this.status === PENDING) {
                this.resolveAsyList.push(() => {
                    try {
                        const result = onResolve(this.result)
                        handlePromise(RESOLVE, result, newPromise, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })
                this.rejectAsyList.push(() => {
                    try {
                        const result = onReject(this.reason)
                        handlePromise(REJECT, result, newPromise, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }

                })
            }
        })
        return newPromise
    }
    this.catch = (onReject) => {
        return this.then(undefined, onReject)
    }
}

module.exports = selfPromise

测试案例:

const myPromise = require('./myPromise_v4')

var test = new myPromise((resolve, reject) => {
    setTimeout(()=>{
        reject("error")
    },1000)
})
test.then(res => {
    console.log("res1", res)
    return "then1"
}, err => {
    console.log("err1",err)
    return err
}).then(res => {
    console.log("res2", res)
}, err => {
    console.log("err2", err)
    return err
}).catch(err=>{
    console.log("catch",err)
})
console.log("同步代码")

至此,我们已经基本把promise对象的基本方法都实现了,除此之外,原生的promise对象还有all,race这两个方法,这个大家可以自行实现,本系列文章到此就告一段落了,如果过程中有错误的希望大家指出,感谢大家的支持,觉得本系统文章有用的老铁可以给作者点个赞,谢谢。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值