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

前言

前一章讲到通过订阅-发布模式,解决了resolve被setTimeout包裹,导致最终结果出不来的bug。但是,原生的promise还有一个很重要的特性,就是可以进行链式调用,then方法的执行结果也是一个promise对象。下面进入本章的正题。

前一章链接:https://blog.csdn.net/weixin_42344533/article/details/117622308

后一章链接:https://blog.csdn.net/weixin_42344533/article/details/117636782

过程

1、上一个版本实现的promise并不能进行链式调用,因为then没有返回promise对象,所以会报错。

2、版本3中实现了then方法的链式调用,效果图如下。

3、 版本3的then方法链式调用实现,主要是对then方法的返回值进行包装(promise包装)+递归加锁的方式实现。所以接下来,就对版本二的then方法进行改造。

4、全局handlePromise方法实现,主要通过递归加锁方式。

总结

then方法的链式调用,主要实现思路有两个点,一个是对then方法的返回值进行promise对象包装,另一个是对上一个then方法的返回值进行递归加锁处理。

实现源码myPromise.js:

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


const handlePromise = (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
        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)
        }
    } else {
        resolve(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.then = (onResolve, onReject) => {
        const newPromise = new selfPromise((resolve, reject) => {
            if (this.status === RESOLVE) {
                setTimeout(() => {
                    const result = onResolve(this.result)
                    handlePromise(result, newPromise, resolve, reject)
                }, 0)
            }
            if (this.status === REJECT) {
                setTimeout(() => {
                    const result = onReject(this.reason)
                    handlePromise(result, newPromise, resolve, reject)
                }, 0)
            }
            if (this.status === PENDING) {
                this.resolveAsyList.push(() => {
                    const result = onResolve(this.result)
                    handlePromise(result, newPromise, resolve, reject)
                })
                this.rejectAsyList.push(() => {
                    const result = onReject(this.reason)
                    handlePromise(result, newPromise, resolve, reject)
                })
            }
        })
        return newPromise
    }
    this.init(exe)
}

module.exports = selfPromise

测试实例test.js:

const myPromise = require('./myPromise_v3')

var test = new myPromise((resolve,reject)=>{
    setTimeout(()=>{
        resolve("这是手动实现的promise")
    },1000)
})

test.then(res=>{
        console.log(res)
        return "这是版本3的then链式调用返回1"
    }).then(res=>{
        console.log(res)
        return "这是版本3的then链式调用返回2"
    }).then(res=>{
        console.log(res)
    })

console.log("同步代码")

下一章将在版本3的基础上实现原生promise的catch的方法,同时对整个promise对象进行异常处理的优化。

后一章链接:https://blog.csdn.net/weixin_42344533/article/details/117636782

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值