Promise 模拟实现

前言

最近很想研究一下Promise的原理,通过查阅资料写出了这篇博客,文章有借鉴参考文档。

正文

本文主要实现的是两个点,基本的Promisethen的链式调用。
代码的所有解释都在注释中

定义状态
//定义状态
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const PENDING = 'pending'
构造函数
function MyPromise(handle) {
    //this.value 是resolve或rejecte状态的值
    this.value = undefined
    //初始化的Promise状态
    this.status = PENDING
    //分别是成功和失败回调函数的队列
    this.fulfilledCallback = []
    this.rejectedCallback = []

    const resolve = value => {
        //只有pending状态才能被改变,reject函数同理
        if (this.status === PENDING) {
            //改变状态
            this.status = FULFILLED
            //赋值给Promise的resolve状态下的值
            this.value = value
            //执行resolve的回调函数
            this.fulfilledCallback.forEach(callback => callback(value))
        }
    }

    const reject = value => {
        if (this.status === PENDING) {
            //改变状态
            this.status = REJECTED
            //赋值给Promise的reject状态下的值
            this.value = value
            //执行reject的回调函数
            this.rejectedCallback.forEach(callback => callback(value))
        }
    }

    try {
        handle(resolve, reject)
    } catch (err) {
        reject(err)
    }
}
then
MyPromise.prototype.then = function (onFulfilled = val=>val, onRejected = err=>{throw err}) {
    //返回一个Promise
    return new MyPromise((resolve, reject) => {
        function handle(callback, value) {
            try {
            	//判断then的参数是否是函数,不是则直接resolve这个新的Promise
                if (typeof callback !== "function") {
                    return resolve(value)
                }

                const result = callback(value)

                if (result instanceof MyPromise) {
                    //如果是Promsise类型,必须等待它的状态改变
                    result.then(resolve, reject)
                } else {
                    //then的默认状态就是resolve
                    resolve(result)
                }
            } catch (err) {
                reject(err)
            }
        }

        //这里的this指向是调用then的那个Promise
        if (this.status === FULFILLED) {
            //同步任务进入
            queueMicrotask(() => {
                handle(onFulfilled, this.value)
            })
        } else if (this.status === REJECTED) {
            //同步任务进入
            queueMicrotask(() => {
                handle(onRejected, this.value)
            })
        } else {
            //异步任务 带着pending状态到这里=>注册回调函数=>等待resolve/reject来执行回调
            //也就是说,如果Promise中的resolve不是异步的,根本注册不了回调函数,不会进入那两个数组
            this.fulfilledCallback.push(value => {
                queueMicrotask(() => {
                    handle(onFulfilled, value)
                })
            })

            this.rejectedCallback.push(value => {
                queueMicrotask(() => {
                    handle(onRejected, value)
                })
            })
        }
    })
}
实际测试
const fs = require('fs')

//为了测试MyPromise,封装了一个读文件函数
function readFile(path) {
    return new MyPromise((resolve, reject) => {
        fs.readFile(path, (err, data) => {
            if (err) {
                reject(err)
            } else {
                resolve(data.toString())
            }
        })
    })
}

readFile('./a.txt')
    .then(data => {
        console.log(data)
        return readFile('./b.txt')
    })
    .then('str')
    .then(data => {
        console.log(data)
    })
    //先输出a文件的内容,在输出b文件的内容,成功
参考文档

手动实现Promise

结语

如果对你有帮助的话,请点一个赞吧

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值