手写一个简单的promise

150 阅读1分钟

1.png 为了加深对promise的理解,手写了一个简便的promise请求,主要是实现then,catch。另外链式调用未实现,还在研究中。

1.YCPromise.js
//初始化三种状态
const RESOLVE = 'resolved';
const REJECT = 'rejected';
const PENDING = 'pending'

class YCPromise {
    result = undefined
    reason = undefined
    status = PENDING      //默认状态
    onResolvedArr = []    
    onRejectdArr = []
    constructor(executor){
        const resolve = (result) => {
            if(this.status === PENDING){
                this.result = result
                this.status = RESOLVE
                this.onResolvedArr.map((fn) => fn())  //执行订阅的函数
            }
        }
        const reject = (reason) => {
            if(this.status === PENDING){
                this.reason = reason
                this.status = REJECT
                this.onRejectdArr.map((fn) => fn())
            }
        }
        executor(resolve,reject)
    };

    then(onResolved,onRejectd){
        if(this.status === RESOLVE){
            setTimeout(() => {  //用setTimeout让自定义变成异步
                onResolved(this.result)
            }, 0);
        }

        if(this.status === REJECT){
            setTimeout(() => {
                onRejectd(this.reason)
            }, 0);
        }

        // 如果then方法执行时,status还是PENDING状态,发布订阅解决这个问题
        if(this.status === PENDING){
            this.onResolvedArr.push(() => {    //发布待执行函数推入列表
                onResolved()
            })
            this.onRejectdArr.push(() => {
                onRejectd()
            })
        }
    };

    catch(onRejectd){
        if(this.status === REJECT){
            if(onRejectd){
                onRejectd(this.reason)
            }else{
                return
            }
        }else{
            return
        }
    }
}

2.测试
let p = new YCPromise((resolve,reject) => {
            let random = Math.floor(Math.random() * 10);
            if (random > 4) {
                resolve('sucess')
            } else {
                reject('erro')
            }
        })

        p.then(value => {
            console.log(value);
        },err => {
            console.log(err);   
        })

        console.log('111111');

image.png

image.png

3.注意点

如果要实现promise的异步,也就是遵循事件循环机制,此处使用到setTimeOut(),页可以使用其他方法。