手写简易Promise

本文详细介绍了如何改进一个简单的Promise实现,解决同步问题和链式调用问题。通过添加异步处理、onFulfilledFn和onRejectedFn数组,以及支持then方法的链式调用,使得Promise更符合A+规范,适用于实际开发场景。
摘要由CSDN通过智能技术生成

先写一个最简单的同步的Promise,

首先根据Promise的A+规范

// Promise三个状态,pending,fulfilled,rejected .两个值value,reason.
// Promise接收回调函数,回调函数的参数为resolve跟reject
//
// then方法
// promise.then(onFulfilled(接受Promise的value值), onRejected(接收Promise的reason值))

//使用try catch处理报错
<script>
    var PENDING = 'pending'
    var FULFILLED = 'fulfilled'
    var REJECTED = 'rejected'
    function myPromise(callBack) {
        var that = this
        that.status = PENDING
        function resolve(value) {
            if (that.status === PENDING){
                that.status = FULFILLED
                that.value = value
            }
        }
        function reject(reason) {
            if (that.status === PENDING){
                that.status = REJECTED
                that.reason = reason
            }
        }
        try{
            callBack(resolve,reject)
        }catch (e) {
            reject(e)
        }
    }

    myPromise.prototype.then = function (onFulfilled,onRejected) {
        onFulfilled = typeof onFulfilled === 'function'? onFulfilled: function (x) {return x}
        onRejected = typeof onRejected === 'function'? onRejected: function (e) {throw e}
        var that = this
        if (that.status ===FULFILLED){
            setTimeout(()=>{
                onFulfilled(that.value)
            })
        }
        if (that.status ===REJECTED){
            setTimeout(()=>{
                onRejected(that.reason)
            })
        }
    }
</script>

上面是一个简易功能的Promise,但是仍有缺陷,
问题
1.Promise异步不能实现
2.then不能被链式调用,then函数的返回值不是promise

解决方法
1.在 PENDING 状态时,需要等到状态落定才能调用。我们可以将 onFulfilled 和 onRejected 函数存到 Promise 的属性 onFulfilledFn 和 onRejectedFn 中,
将 onFulfilledFn 和 onRejectedFn 改成数组。.resolve() 和 reject() 函数改变状态时,需要异步调用数组中的函数,同样使用 setTimeout 来模拟异步。

所以需要写的东西有:

        that.onFulfilledFn=[]
        that.onRejectedFn=[]

        function resolve(value) {
            setTimeout(function () {
                if (that.state === PENDING) {
                    that.state = FULFILLED
                    that.value = value
                    that.onFulfilledFn.forEach(item=>item(that.value))
                }
            })
        }
        if (that.state === PENDING) {
            return new myPromise(function (resolve,reject) {
                that.onFulfilledFn.push(function() {
                    try {
                        onFulfilled(that.value);
                    } catch (reason) {
                        reject(reason);
                    }
                })
                that.onRejectedFn.push(function() {
                    try {
                        onRejected(that.reason);
                    } catch (reason) {
                        reject(reason);
                    }
                });
            })
        }

2.链式调用,then返回一个新的promise,直接在方法里return new myPromise

<script>
    // A+规范
    //
    // Promise三个状态,pending,fulfilled,rejected .两个值value,reason.
    // Promise接收回调函数,回调函数的参数为resolve跟reject
    //
    // then方法
    // promise.then(onFulfilled(接受Promise的value值), onRejected(接收Promise的reason值))

    //使用try catch处理报错


    // 1.then 方法接受两个函数作为参数,且参数可选。
    // 2.如果可选参数不为函数时会被忽略。
    // 3.两个函数都是异步执行,会放入事件队列等待下一轮 tick。
    // 4.当调用 onFulfilled 函数时,会将当前 Promise 的 value 值作为参数传入。
    // 5.当调用 onRejected 函数时,会将当前 Promise 的 reason 失败原因作为参数传入。
    // 6.then 函数的返回值为 Promise。
    // 7.then 可以被同一个 Promise 多次调用(then的链式)。

    // * 1. new Promise时,需要传递一个 executor 执行器,执行器立刻执行
    // * 2. executor 接受两个参数,分别是 resolve 和 reject
    // * 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled
    // * 4. promise 的状态一旦确认,就不会再改变
    // * 5. promise 都有 then 方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled,
    // *      和 promise 失败的回调 onRejected
    // * 6. 如果调用 then 时,promise已经成功,则执行 onFulfilled,并将promise的值作为参数传递进去。
    // *      如果promise已经失败,那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。
    // *      如果promise的状态是pending,需要将onFulfilled和onRejected函数存放起来,等待状态确定后,再依次将对应的函数执行(发布订阅)
    // * 7. then 的参数 onFulfilled 和 onRejected 可以缺省
    // * 8. promise 可以then多次,promise 的then 方法返回一个 promise
    // * 9. 如果 then 返回的是一个结果,那么就会把这个结果作为参数,传递给下一个then的成功的回调(onFulfilled)
    // * 10. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个then的失败的回调(onRejected)
    // * 11.如果 then 返回的是一个promise,那么会等这个promise执行完,promise如果成功,
    // *   就走下一个then的成功,如果失败,就走下一个then的失败
    // *




    var PENDING = 'pending';
    var FULFILLED = 'fulfilled';
    var REJECTED = 'rejected';

    //简易Promise,传入一个回调函数,回调函数的参数是resolve()和reject()
    function myPromise(callBack) {
        var that = this;
        that.state = PENDING

        that.onFulfilledFn = [];
        that.onRejectedFn = [];


        function resolve(value) {
            setTimeout(function () {
                if (that.state === PENDING) {
                    that.state = FULFILLED
                    that.value = value;
                    that.onFulfilledFn.forEach(function (fn) {
                        fn(that.value)
                    })
                }
            })
        }

        function reject(reason) {
                setTimeout(function () {
                    if (that.state === PENDING) {
                        that.state = REJECTED
                        that.reason = reason
                        that.onRejectedFn.forEach(function(fn){
                            fn(that.reason)
                        })
                    }
                })
        }


        //Promise 内部的异常不能直接抛出,需要进行异常捕获。
        try {
            callBack(resolve, reject)
        } catch (e) {
            reject(e)
        }
    }


    //原型定义方法和共享属性
    myPromise.prototype.then = function (onFulfilled, onRejected) {
        //then规则2,可选参数不为函数时应该被忽略
        onFulfilled = typeof onFulfilled === "function" ? onFulfilled : function (x) {
            return x
        }
        onRejected = typeof onRejected === "function" ? onRejected : function (e) {
            throw e
        }

        var that = this;


        //以下if语句为对onFulfilled, onRejected等方法传参,then规则3异步,then规则4,5
        //then规则6,then返回Promise
        if (that.state === FULFILLED) {
            return new myPromise((resolve, reject) => {
                setTimeout(function () {
                    try {
                        onFulfilled(that.value)
                    } catch (e) {
                        reject(e)
                    }
                })
            })
        }
        if (that.state === REJECTED) {
            return new myPromise((resolve, reject) => {
                setTimeout(function () {
                    try {
                        onRejected(that.reason)
                    } catch (e) {
                        reject(e)
                    }
                })
            })
        }
        //在 PENDING 状态时,需要等到状态落定才能调用。我们可以将 onFulfilled 和 onRejected 函数存到 Promise 的属性 onFulfilledFn 和 onRejectedFn 中
        //为了支持then的链式调用,下面的代码如
        if (that.state === PENDING) {
            return new myPromise(function(resolve, reject) {
                that.onFulfilledFn.push(function() {
                    try {
                        onFulfilled(that.value);
                    } catch (reason) {
                        reject(reason);
                    }
                })
                that.onRejectedFn.push(function() {
                    try {
                        onRejected(that.reason);
                    } catch (reason) {
                        reject(reason);
                    }
                });
            });
        }
    }






    let Fsskay = new myPromise((resolve, reject) => {
        setTimeout(function () {
            resolve(123)
        },1000)
    })
    Fsskay.then((data) => {
        console.log(data)
    })
    console.log(Fsskay)

</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值