手写Promise1.0

学习笔记,手写promise1.0,实现promise类与then方法。

1.首先是myPromise类的实现

我们首先定义三个静态变量来表示myPromise的状态,分别是PROMISE_STATUS_PENDING、PROMISE_STATUS_RESOLVE和PROMISE_STATUS_REJECT,它们分别表示myPromise的pending、resolve和reject状态。 然后我们在myPromise类中定义了value变量与reason变量来保存resolve与reject中传入的值。 onFulfilledCallbacks与onRejectedCallbacks分别保存resolve与reject中要调用的回调函数。

接着我们来实现resolve与reject函数,当myPromise的状态为pending时才执行resolve中的操作,将传入的value值保存在this.value中,将myPromise的状态设置为fulfilled,然后依次执行onFulfilledCallbacks中的回调函数,reject函数也是同样的道理。

js 复制代码
class myPromise {
    static PROMISE_STATUS_PENDING = 'pending'
    static PROMISE_STATUS_RESOLVE = 'fulfilled'
    static PROMISE_STATUS_REJECT = 'rejected'
    value = undefined
    reason = undefined
    status = myPromise.PROMISE_STATUS_PENDING
    onFulfilledCallbacks = []
    onRejectedCallbacks = []
    constructor(execute) {
        const resolve = (value) => {
            if (this.status === myPromise.PROMISE_STATUS_PENDING) {
                this.value = value
                this.status = myPromise.PROMISE_STATUS_RESOLVE
                this.onFulfilledCallbacks.forEach(callBack => callBack(this.value))
            }
        }
        const reject = (reason) => {
            if (this.status === myPromise.PROMISE_STATUS_PENDING) {
                this.reason = reason
                this.status = myPromise.PROMISE_STATUS_REJECT
                this.onRejectedCallbacks.forEach(callBack => callBack(this.reason))
            }
        }
        try {
            execute(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }
}

2.then方法的实现

首先我们需要判断then函数中当myPromise状态变为成功或失败时的回调函数的类型,如果它们不是函数,就将他们替换为返回自身值的函数。

为了实现then方法的链式调用,then方法的返回值是一个新的myPromise实例,1. 它根据当前MyPromise实例的状态来执行以下操作之一: - 如果状态是FULFILLED,则执行onFulfilled回调,并将结果传递给新Promise的解析函数。 - 如果状态是REJECTED,则执行onRejected回调(如果存在),并将结果传递给新Promise的拒绝函数。 - 如果状态是PENDING,则将onFulfilled和onRejected回调添加到相应的回调数组中,以便在状态变化时执行。

如果当前状态为已完成状态,如果当前状态为fulFilled,则执行onFulfilled回调函数,将回调函数的执行放入微任务队列,确保回调函数的异步执行。使用handleRes工具函数来处理回调函数的执行结果,已拒绝状态的处理思路是同样的。如果当前状态是pending(或其他未解决状态),则将onFulfilled和onRejected回调函数分别添加到onFulfilledCallBacks和onRejectedCallBacks数组中,以便在状态变化时执行。

js 复制代码
then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (onFulfilled) => onFulfilled
        onRejected = typeof onRejected === 'function' ? onRejected : (onRejected) => onRejected

        return new myPromise((resolve, reject) => {
            // 处理已完成状态
            if (this.status === myPromise.PROMISE_STATUS_RESOLVE) {
                try {
                    queueMicrotask(() => {
                        const res = onFulfilled(this.value)
                        this.handleRes(res, resolve, reject)
                    })
                } catch (error) {
                    reject(error)
                }
            }
            // 处理已拒绝状态
            else if (this.status === myPromise.PROMISE_STATUS_REJECT) {
                try {
                    queueMicrotask(() => {
                        const res = onRejected(this.reason)
                        this.handleRes(res, resolve, reject)
                    })
                } catch (error) {
                    reject(error)
                }
            }
            // 处理异步状态
            else {
                this.onFulfilledCallbacks.push((value) => {
                    queueMicrotask(() => {
                        const res = onFulfilled(value)
                        this.handleRes(res, resolve, reject)
                    })
                })
                this.onRejectedCallbacks.push((reason) => {
                    queueMicrotask(() => {
                        const res = onRejected(reason)
                        this.handleRes(res, resolve, reject)
                    })
                })
            }
        })
    }
    //处理then方法中回调函数的结果。
    handleRes(res, resolve, reject) {
    //判断结果是否为myPromise实例
        if (res instanceof myPromise) {
        //如果是,递归调用then方法,将当前的resolve和reject作为参数传递。
            res.then(resolve, reject)
        } else {
        //如果不是,则直接调用resolve方法解析这个值
            resolve(res)
        }
    }

这样,我们就实现了一个简单的myPromise类与then方法。 下面是我写的测试用例:

js 复制代码
// 测试myPromise的状态管理与连续调用then方法
const promise = new myPromise((resolve, reject) => {
    resolve(111)
    reject(222)
})
promise.then(res => {
    console.log('res1', res);
}, err => {
    console.log('err1', err);
})

promise.then(res => {
    console.log('res2', res);
}, err => {
    console.log('err2', err);
})

// 延迟调用then方法
setTimeout(() => {
    promise.then(res => {
        console.log('res3', res);
    }, err => {
        console.log('err3', err);
    })
}, 1000)

// then方法的链式调用
promise.then(res => {
    return {"res4":res}
}, err => {
    console.log('err4', err);
}).then(res => {
    console.log('res5', res);
}, err => {
    console.log("err5", err);
})
相关推荐
还是大剑师兰特30 分钟前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
一只小白菜~36 分钟前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding41 分钟前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
阿征学IT1 小时前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓1 小时前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
发现你走远了1 小时前
『VUE』25. 组件事件与v-model(详细图文注释)
前端·javascript·vue.js
吖秧吖1 小时前
three.js 杂记
开发语言·前端·javascript
前端小超超1 小时前
vue3 ts项目结合vant4 复选框+气泡弹框实现一个类似Select样式的下拉选择功能
前端·javascript·vue.js
大叔是90后大叔1 小时前
vue3中查找字典列表中某个元素的值
前端·javascript·vue.js
IT大玩客1 小时前
JS如何获取MQTT的主题
开发语言·javascript·ecmascript