手写简单Promise

146 阅读1分钟

众所周知,promise虽然本质上也是回调,但是解决了令人眼花撩乱的地狱回调问题,也可以链式调用,同时也对等待多个异步网络请求后处理问题很友好,那现在咱们来手写一个简单的promise呗。

promise 只有三种状态,pending,fullfilled和rejected,默认是pending状态,通过调用resolve方法将状态变为fullfilled,调用reject方法或者同步代码块抛出异常时,将状态变为rejected,并且一旦是fullfilled或者rejected状态,就不能再改变状态了。

const PENDING = 'PENDING'const FULLFILLED = 'FULLFILLED'const REJECTED = 'REJECTED'class MyPromise {    constructor(excutor) {        this.status = PENDING        this.value = undefined // 成功参数        this.reason = undefined // 失败原因        // 发布订阅模式, 订阅回调函数,excutor有异步宏任务时        this.fullfilledList = [] // 成功回调        this.rejectedList = [] // 失败回调        this.resolve = (val) => {            if (this.status === PENDING) {                this.status = FULLFILLED                this.value = val                // 发布成功回调                this.fullfilledList.forEach(cb => cb())            }        }        this.reject = (val) => {            if (this.status === PENDING) {                this.status = REJECTED                this.reason = val                // 发布失败回调                this.rejectedList.forEach(cb => cb())            }        }        try {            excutor(this.resolve, this.reject)        } catch (e) {            this.reject(e)        }    }    then(onFullfilled, onRejected) {        if (this.status === FULLFILLED) {            onFullfilled(this.value)        }        if (this.status === REJECTED) {            onRejected(this.reason)        }        if (this.status === PENDING) {            this.fullfilledList.push(() => {                onFullfilled(this.value)            })            this.rejectedList.push(() => {                onRejected(this.reason)            })        }        // 链式模式        return this    }}new MyPromise((resolve, reject) => {    setTimeout(() => {        reject('failed') // 会被执行    }, 0)}).then(resolve => {    console.log(resolve)}, reject => {    console.log(reject)}).then(resolve => {    console.log(resolve)}, reject => {    console.log(reject)})new MyPromise((resolve, reject) => {    setTimeout(() => {        reject('failed') // 不会被执行    }, 0)    process.nextTick(() => {        resolve('success')    })}).then(resolve => {    console.log(resolve)}, reject => {    console.log(reject)}).then(resolve => {    console.log(resolve)}, reject => {    console.log(reject)})