手写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);
})
相关推荐
百万蹄蹄向前冲1 小时前
2024不一样的VUE3期末考查
前端·javascript·程序员
alikami2 小时前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
wakangda2 小时前
React Native 集成原生Android功能
javascript·react native·react.js
吃杠碰小鸡2 小时前
lodash常用函数
前端·javascript
emoji1111113 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
一个处女座的程序猿O(∩_∩)O3 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
User_undefined3 小时前
uniapp Native.js原生arr插件服务发送广播到uniapp页面中
android·javascript·uni-app
麦兜*3 小时前
轮播图带详情插件、uniApp插件
前端·javascript·uni-app·vue
陈大爷(有低保)3 小时前
uniapp小案例---趣味打字坤
前端·javascript·vue.js
博客zhu虎康3 小时前
ElementUI 的 form 表单校验
前端·javascript·elementui