promise自定义封装(手写promise)源码


highlight: a11y-dark

一、基本框架实现

实现以下结构的promise自定义封装

<script>
    const p=new Promise((resolve,reject)=>{
        resolve('ok')
        // reject('err')
        // throw('err')
}).then((value)=>{
    console.log(value)
}(reason)=>{
    console.log(reason)
})
</script>

步骤:

1. 初始结构状态搭建

2. resolve与reject结构搭建

3. throw抛出异常状态改变

4. promise对象状态只修改一次

5. then方法执行回调

<script>
//1.构造函数
function Promise(executor){
    //添加属性
    //设置初始状态
    this.Promisestate ='pedding'
    //设置初始值
    this.PromiseResult = null
    //保存实例对象的this值
    const self = this
    //2. resolve与reject结构搭建
    function resolve(data){
        //判断  4. promise对象状态只修改一次
        if(self.PromiseState !== 'pedding')return
        //(1)修改对象状态(Promisestate)
        self.Promisestate='fulfilled'//resolved 解决
        //(2)设置对象结果值(PromiseResult)
        self.PromiseResult = data
    }
    function reject(data){
        //判断  4. promise对象状态只修改一次
        if(self.PromiseState !== 'pedding')return
        //(1)修改对象状态(Promisestate)
        self.PromiseState="rejected"
        //(2)设置对象结果值(PromiseResult)
        self.PromiseResult=data
    }
    //3. throw抛出异常状态改变
    try {
        //同步调用[执行器函数]
        executor(resolve,reject)
    }catch(e){
        //修改promise对象状态为失败
        reject(e)
    }
}

//5.添加then方法 (then方法执行回调)
Promise.prototype.then=function(onResolve, onReject){
    //调用回调函数 Promisestate
    if(this.PromiseState ==='fulfilled'){
        onResolve(this.PromiseResult)
     }
    if(this.PromiseState ==='rejected'){
        onReject(this.PromiseResult)
     }
 }
</script>

二、异步任务回调的执行

setTimeout模拟异步任务回调

<script>
const p=new Promise((resolve,reject)=>{
       setTimeout(()=>{
            resolve('oK');
        }1000);
        // reject('err')
        // throw('err')
}).then((value)=>{
    console.log(value)
}(reason)=>{
    console.log(reason)
})
</script>
  • (异步)回调执行时机:在改变对象状态之后才执行的回调函数
  • 同步执行的时机就是在调用then方法的时候调用回调函数
  1. 在状态改变之前先保存回调函数,注意先声明callback属性

this.callback={}

image.png

  1. 调用成功/失败时的回调函数

image.png

三、指定多个回调的实现

image.png

指定多个回调,这种写法就会使后面的对象覆盖前面的,只会执行alert;

企业微信截图_17149673203975.png

解决办法,把多个回调函数存在数组里;

image.png

修改callback定义,且利用forEach遍历数组对象

image.png

image.png

四、同步修改状态then方法结果返回

image.png

结果:

image.png

(因为上述回调函数没有加return,所以PromiseResult为undifined)

同理reject状态执行结果:
image.png
关键:如果.then后面的函数返回的是非promise状态的函数,比如undifine,字符串等,状态都是resolve状态的;如果返回的是promise状态的,这个返回的promise状态就决定了.then结果的状态

实现源码:

image.png

then方法返回结果:

  1. 非promise对象的reslove;
  2. promise对象的resolve和reject;
  3. 抛出异常情况下,改变状态为失败的reject;

image.png

抛出异常情况

image.png

五、异步修改状态then方法结果返回

image.png

image.png
此时状态还是pending,但是这里正确的Promise的then方法返回的应该是

image.png

所以我们要修改异步情况下then返回的状态结果;
因为此时状态还是pending,我们要在PromiseState===pedding时进行执行

image.png
同时,执行过程同理:
then方法返回结果:

  1. 非promise对象的reslove;
  2. promise对象的resolve和reject;
  3. 抛出异常情况下,改变状态为失败的reject;

image.png

代码优化

image.png

六、catch方法-异常穿透和值传递

image.png
异常穿透:就是在最后指定一个失败的回调,就可以对失败的结果进行处理,包括中间有可能抛出的异常

image.png

第一个p.then执行了,紧跟着传的回调函数的参数,传的是onRejected,是一个非函数
image.png
值传递
image.png

七、Promise.resolve封装

image.png
(返回的是promise的对象,返回的状态决定Promise.resolve去执行什么状态;返回的是成功,Promise.resolve就是去执行成功,返回的是失败,Promise.resolve就是去执行失败,返回的是非promise对象。就设置状态为成功)

八、Promise.reject封装

Promise.rejectPromise.resolve的不同就是,不管传什么参数,都是执行reject

image.png

九、Promise.all封装

image.png

如果有一个失败就是返回失败的那一个的状态

image.png

十、Promise.race封装

image.png
Promise.race的结果由数组中第一个改变的状态的promise决定

image.png

十一、then方法回调的异步执行

image.png

image.png

image.png

image.png

源码

//声明构造函数  
function Promise(executor) {  
    //添加属性  
    //设置初始状态  
    this.PromiseState = 'pedding'//初始状态  
    //设置初始值  
    this.PromiseResult = null  
    //保存实例对象的this值  
    const self = this  
    //声明属性  
    this.callback = []
    //resolve函数  
    function resolve(data) {  
        //判断  
        if (self.PromiseState !== 'pedding') return  
        //1.修改对象状态(PromiseState)  
        self.PromiseState = 'fulfilled'//resolved 解决  
        //2.设置对象结果值(PromiseResult)  
        self.PromiseResult = data  
        //调用成功的回调函数  
        //如果self.callback里面有onResolved  
        // if (self.callback.onResolved) {  
        //     self.callback.onResolved(data)  
        // }  
        setTimeout(() => {  
            self.callback.forEach(item => {  
                item.onResolved(data)  
            })  
        })  
    }
    //reject函数  
    function reject(data) {  
        //判断  
        if (self.PromiseState !== 'pedding') return  
        //1.修改对象状态(PromiseState)  
        self.PromiseState = 'rejected'  
        //2.设置对象结果值(PromiseResult)  
        self.PromiseResult = data  
        //调用失败的回调函数  
        //如果self.callback里面有onRejected  
        // if (self.callback.onRejected) {  
        //     self.callback.onRejected(data)  
        // }  
        setTimeout(() => {  
            self.callback.forEach(ittem => {  
                item.onRejected(data)  
            })  
        })  
    }
    try {  
        //同步调用[执行器函数]  
        executor(resolve, reject)  
    } catch (e) {  
        //修改promise对象状态为失败  
        reject(e)  
    }  
}


//添加then方法  
Promise.prototype.then = function (onResolve, onReject) {  
    const self = this  
    //判断回调函数的参数  
    if (typeof onRejected !== 'function') {  
        onRejected = reason => {  
            throw reason  
        }  
    }  
    //值传递 第一个不传 就给它赋默认值  
    if (typeof onResolved !== 'function') {  
        onResolved = value => value  
    }  
    return new Promise((resolve, reject) => {  
        //封装函数  
        function callback(type) {  
            try {  
                let result = type(self.PromiseResult)  
                //判断  
                if (result instanceof Promise) {  
                    //如果是promise类型对象  
                    result.then(v => {  
                        resolve(v)  
                    }, r => {  
                        reject(r)  
                    })
                 } else {  
                    //如果是非promise类型对象  
                    //结果状态为成功  
                    resolve(result)  
                }  
            } catch (e) {  
                reject(e)  
            }  
        }  
        //调用回调函数 PromiseState  
        if (this.PromiseState === 'fulfilled') {  
            setTimeout(() => { callback(onResolve) })  
        }  
        if (this.PromiseState === 'rejected') {  
            setTimeout(() => { callback(onReject) })  
        }  
        // (异步)回调执行时机:在改变对象状态之后才执行的回调函数  
        if (this.PromiseState === 'pedding') {  
            //保存回调函数  
            this.callback.push = ({  
                onResolve: function () {  
                    callback(onResolve)  
                },  
                onReject: function () {  
                    callback(onReject)  
                },  
            })  
        }  
    })  
}


//添加catch方法  
Promise.prototype.catch = function (onRejected) {  
    //说明: then()的语法糖, 相当于: then(undefined, onRejected)  
    return this.then(undefined, onRejected)  
}


//添加resolve方法  
Promise.resolve = function (value) {  
    //返回Promise对象  
    return new Promise((resolve, reject) => {  
        if (value instanceof Promise) {  
            value.then(v => {  
                resolve(v)  
            }, r => {  
                reject(r)  
            })  
        } else {  
            //状态设置为成功  
            resolve(value)  
        }  
    })  
}


//添加reject方法  
Promise.reject = function (reason) {  
    return new Promise((reason, reject) => {  
        reject(reason)  
    })  
}


//添加all方法  
Promise.all = function (promise) {  
    //返回结果为promise对象  
    return new Promise((resolve, reject) => {  
        let count = 0  
        let arr = []  
        //遍历  
        for (let i = 0; i < promise.length; i++) {  
            promise[i].then(v => {  
                //得知对象的状态是成功  
                //每个promise对象都成功  
                count++  
                //将当前promise对象成果的结果存入到数组  
                arr[i] = v  
                //判断  
                if (count === promise.length) {  
                    //修改状态  
                    resolve(arr)  
                }  
            }, r => {  
                reject(r)  
            })  
        }  
    })  
}


//添加race方法  
Promise.race = function (promise) {  
    return new Promise((resolve, reject) => {  
        for (let i = 0; i < promise.length; i++) {  
            promise[i].then(v => {  
                //修改返回对象的状态为[成功]  
                resolve(v)  
            }, r => {  
                //修改返回对象的状态为[失败]  
                reject(r)  
            })  
        }  
    })  
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值