手写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);
})
相关推荐
一路向前的月光4 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   4 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web4 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
Jiaberrr5 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
安冬的码畜日常7 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js
太阳花ˉ7 小时前
html+css+js实现step进度条效果
javascript·css·html
john_hjy7 小时前
11. 异步编程
运维·服务器·javascript
风清扬_jd8 小时前
Chromium 中JavaScript Fetch API接口c++代码实现(二)
javascript·c++·chrome
yanlele8 小时前
前瞻 - 盘点 ES2025 已经定稿的语法规范
前端·javascript·代码规范