手写promise

一、前言

        大家都知道做前端开发的时候最让人头痛的就是处理异步请求的情况,在请求到的成功回调函数里继续写函数,长此以往形成了回调地狱。

1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:

  • pending: 初始状态,不是成功或失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。

2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

二、手写一个promise

class myPromise {
    // promise 有三种状态未处理的、成功的、失败的
    static PENDING = 'pending'
    static FULFILL = 'fulfill'
    static REJECT = 'REJECT'
    constructor(result) {
        // 初始状态
        this.state = myPromise.PENDING
        this.value = null;
        // 当出现错误的时候需要补货
        try {
            // 当我们new一个对象的时候,this的指向被引向全局。window需要更改使用方向
            result(this.resolve.bind(this), this.reject.bind(this))
        } catch (err) {
            this.reject(err)
        }

    }
    resolve(value) {
        // 因为结果是不可逆的需要判断
        if (this.state === 'pending') {
            this.state = myPromise.FULFILL
            this.value = value
        }
    }
    reject(reason) {
        if (this.state === 'pending') {
            this.state = myPromise.REJECT
            this.reason = reason
        }
    }
}

在写一个then方法,这个时候写的promise并不是异步方法。

// then有成功与失败的回调
    then(succeed, fail) {
        // 当succeed与fail不是函数会出现报错
        if (typeof (succeed) !== 'function') {
            succeed = () => {}
        }
        if (typeof (fail) !== 'function') {
            fail = () => {}
        }
        // 判断失败或是成功
        if (this.state === myPromise.FULFILL) {
            // 当有错误的时候需要捕获错误
            try {
                succeed(this.value)
            } catch (err) {
                console.log(err);
            }
        } else if (this.state === myPromise.REJECT) {
            try {
                fail(this.value)
            } catch (err) {
                console.log(err);
            }
        }
    }

 添加定时器将这个方法放入任务队列

 then(succeed, fail) {
        // 当succeed与fail不是函数会出现报错
        if (typeof (succeed) !== 'function') {
            succeed = () => {}
        }
        if (typeof (fail) !== 'function') {
            fail = () => {}
        }
        // 判断失败或是成功
        if (this.state === myPromise.FULFILL) {
            setTimeout(() => {
                // 当有错误的时候需要捕获错误
                try {
                    succeed(this.value)
                } catch (err) {
                    console.log(err);
                }
            }, 0)

        } else if (this.state === myPromise.REJECT) {
            setTimeout(() => {
                try {
                    fail(this.value)
                } catch (err) {
                    console.log(err);
                }
            }, 0);

        }
    }

处理链式操作,在构造函数里面添加一个callback数组,在状态改变后提取出状态一步步执行

// then有成功与失败的回调
    then(succeed, fail) {
        // 当succeed与fail不是函数会出现报错
        if (typeof (succeed) !== 'function') {
            succeed = () => {}
        }
        if (typeof (fail) !== 'function') {
            fail = () => {}
        }
        // 通过递归实现链式操作
        return new myPromise((resolve, reject) => {
            // 执行到这里的时候状态为pending
            if (this.state === myPromise.PENDING) {
                this.callback.push({
                    succeed: value => {
                        // 当发生错误时交给错误结果统一处理
                        try {
                            //链式结果的状态需要放回给下一个
                            let result = succeed(value)
                            resolve(result)
                        } catch (error) {
                            fail(error)
                        }
                    },
                    fail: value => {
                        try {
                            //链式结果的状态需要放回给下一个
                            let result = fail(value)
                            resolve(result)
                        } catch (error) {
                            fail(error)
                        }
                    }
                })
            }
            // 判断失败或是成功
            if (this.state === myPromise.FULFILL) {
                setTimeout(() => {
                    // 当有错误的时候需要捕获错误
                    try {
                        //链式结果的状态需要放回给下一个
                        let result = succeed(this.value)
                        resolve(result)
                    } catch (err) {
                        console.log(err);
                    }
                }, 0)

            } else if (this.state === myPromise.REJECT) {
                setTimeout(() => {
                    try {
                        //链式结果的状态需要放回给下一个
                        let result = fail(this.value)
                        resolve(result)
                    } catch (err) {
                        console.log(err);
                    }
                }, 0);

            }
        })

    }

完整代码

class myPromise {
    // promise 有三种状态未处理的、成功的、失败的
    static PENDING = 'pending'
    static FULFILL = 'fulfill'
    static REJECT = 'REJECT'
    constructor(result) {
        // 初始状态
        this.state = myPromise.PENDING
        this.value = null;
        this.callback = [];
        // 当出现错误的时候需要补货
        try {
            // 当我们new一个对象的时候,this的指向被引向全局。window需要更改使用方向
            result(this.resolve.bind(this), this.reject.bind(this))
        } catch (err) {
            this.reject(err)
        }

    }
    resolve(value) {
        // 因为结果是不可逆的需要判断
        if (this.state === 'pending') {
            this.state = myPromise.FULFILL
            this.value = value
            // 状态改变后在数组里面使用 
            // 因为需要一直在异步操作
            setTimeout(() => {
                this.callback.map(item => {
                    item.succeed(value)
                })
            }, 0);

        }
    }
    reject(reason) {
        if (this.state === 'pending') {
            this.state = myPromise.REJECT
            this.reason = reason
            // 状态改变后在数组里面使用 
            setTimeout(() => {
                this.callback.map(item => {
                    item.fall(reason)
                })
            }, 0);

        }
    }
    // then有成功与失败的回调
    then(succeed, fail) {
        // 当succeed与fail不是函数会出现报错
        if (typeof (succeed) !== 'function') {
            succeed = () => {}
        }
        if (typeof (fail) !== 'function') {
            fail = () => {}
        }
        // 通过递归实现链式操作
        return new myPromise((resolve, reject) => {
            // 执行到这里的时候状态为pending
            if (this.state === myPromise.PENDING) {
                this.callback.push({
                    succeed: value => {
                        // 当发生错误时交给错误结果统一处理
                        try {
                            //链式结果的状态需要放回给下一个
                            let result = succeed(value)
                            resolve(result)
                        } catch (error) {
                            fail(error)
                        }
                    },
                    fail: value => {
                        try {
                            //链式结果的状态需要放回给下一个
                            let result = fail(value)
                            resolve(result)
                        } catch (error) {
                            fail(error)
                        }
                    }
                })
            }
            // 判断失败或是成功
            if (this.state === myPromise.FULFILL) {
                setTimeout(() => {
                    // 当有错误的时候需要捕获错误
                    try {
                        //链式结果的状态需要放回给下一个
                        let result = succeed(this.value)
                        resolve(result)
                    } catch (err) {
                        console.log(err);
                    }
                }, 0)

            } else if (this.state === myPromise.REJECT) {
                setTimeout(() => {
                    try {
                        //链式结果的状态需要放回给下一个
                        let result = fail(this.value)
                        resolve(result)
                    } catch (err) {
                        console.log(err);
                    }
                }, 0);

            }
        })

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!以下是一个简单的手写Promise的示例: ```javascript class Promise { constructor(executor) { this.state = 'pending'; this.value = undefined; this.reason = undefined; this.onResolveCallbacks = []; this.onRejectCallbacks = []; const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; this.onResolveCallbacks.forEach(callback => callback()); } }; const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected'; this.reason = reason; this.onRejectCallbacks.forEach(callback => callback()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { const fulfilledHandler = typeof onFulfilled === 'function' ? onFulfilled : value => value; const rejectedHandler = typeof onRejected === 'function' ? onRejected : reason => { throw reason; }; const promise2 = new Promise((resolve, reject) => { const fulfillHandlerWrapper = () => { setTimeout(() => { try { const result = fulfilledHandler(this.value); resolvePromise(promise2, result, resolve, reject); } catch (error) { reject(error); } }, 0); }; const rejectHandlerWrapper = () => { setTimeout(() => { try { const result = rejectedHandler(this.reason); resolvePromise(promise2, result, resolve, reject); } catch (error) { reject(error); } }, 0); }; if (this.state === 'fulfilled') { fulfillHandlerWrapper(); } else if (this.state === 'rejected') { rejectHandlerWrapper(); } else { this.onResolveCallbacks.push(fulfillHandlerWrapper); this.onRejectCallbacks.push(rejectHandlerWrapper); } }); return promise2; } catch(onRejected) { return this.then(null, onRejected); } } function resolvePromise(promise, result, resolve, reject) { if (promise === result) { return reject(new TypeError('Chaining cycle detected for promise')); } let thenCalledOrThrow = false; if (result instanceof Promise) { result.then( value => resolvePromise(promise, value, resolve, reject), reason => reject(reason) ); } else if (result !== null && (typeof result === 'object' || typeof result === 'function')) { try { const then = result.then; if (typeof then === 'function') { then.call( result, value => { if (thenCalledOrThrow) return; thenCalledOrThrow = true; resolvePromise(promise, value, resolve, reject); }, reason => { if (thenCalledOrThrow) return; thenCalledOrThrow = true; reject(reason); } ); } else { resolve(result); } } catch (error) { if (thenCalledOrThrow) return; thenCalledOrThrow = true; reject(error); } } else { resolve(result); } } ``` 这只是一个基本的实现,还有很多细节和功能可以改进。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值