JS(16) 手写Promise构造函数

想看直接看手写Promise构造函数,可直接翻到最下面的代码

1、基础知识点

  • 先讲涉及promise的基础知识点(我只是简略涉及,具体可以去看翻阅MDN文档)

  • Promise是一种处理异步代码(而不会陷入回调地狱)的方式

  • Promise有三种状态:pending(初始状态,待定),fulfilled(表示操作完成),rejected(表示操作失败)

  • 它的状态存放在属性[[PromiseState]]中

  • 当new一个Promise来生成一个实例对象时,它接收一个回调函数,这个回调函数接收两个参数resolve和reject,这两个参数也是函数,当操作成功完成时调用resolve,操作失败时调用reject

  • 调用resolve后,实例对象的状态变为fulffiled

  • 调用rejected后,实例函数的状态变为rejected

  • 也可以通过抛出异常,来将实例对象的状态变为rejected

  • 注意:promise的状态只能修改一次

  • Promise上还存有属性[[PromiseResult]],上面放在异步任务成功或失败的结果,通过resolve函数,或者reject函数修改

  • 需要说明的是,Promise中接收的这个回调函数是个立即执行的函数,即称执行函数

  • 操作完成,实例对象改变状态后,可以调用then方法或者catch方法。then方法接收两个回调函数,当实例对象的状态是fulfilled的时执行第一个回调函数,当实例对象的状态是rejected时,执行第二个回调函数

  • 并且then方法得回调函数其接收的参数便是[[PromiseResult]]上的值

在这里插入图片描述


2、相关API

在手写之前,还需要再来说说Promise的几个API的用法,

2.1、Promise(excutor{})

  • excutor是一个执行函数,会在你声明Promise时,就在Promise内部立即同步执行,异步操作在执行器中执行
let a = new Promise(()=>{
    console.log('1')
})
console.log('2',a)
//最后执行结果
// 1
// 2
//Promise{}

2.2、Promise.prototype.then((value)=>{},(reason)=>{})

  • 状态为fulfilled时,调用第一个回调函数
  • 状态为rejected时,调用第二个回调函数
  • then方法也会返回一个Promise对象
    • 如果then()return了一个值,那么then返回得Promise将会变为成功状态,并且其[[PromiseResult]]上的值也会变为返回的这个值
    • 让雨果then()return了一个Promise对象,那么如果这个Promise对象状态是成功的,则then返回一个成功的Promise对象,如果这个Promise对象状态是失败,则tehn返回一个失败的Promise对象。并且其[[PromiseResult]]上的值都相同

2.3、Promise.prototype.catch(reason=>{})

  • 只能执行失败的回调函数

2.4、Promise.resolve()

  • 该方法属于Promise构造函数上的方法,而不是属于实例对象的方法
  • resolve接收一个参数,然后返回一个成功/失败的promise对象
  • 如果传入的参数是非promise类型的对象,则返回的结果是状态为成功的promise对象
  • 如果传入的参数是一个Promise对象,
    • 当这个Promise对象的状态是成功时,则返回一个状态为成功的Promise对象,并且其[[PromiseResult]]上的值也相同
    • 当这个Promise对象的状态是失败时,则返回一个状态为失败的Promise对象,并且其[[PromiseResult]]上的值也相同

2.5、Promise.reject()

  • Promise.reject(),该方法属于Promise函数对象的,而不是属于实例对象的。
  • 该方法是接受一个参数,然后快速返回一个失败的promise对象
  • 并且[[PromiseResult]]上的值就是这个传入的参数

2.6、Pomise.all()

  • 该方法属于Promise函数对象的,而不是属于实例对象的。
    • 它接收一个有Promise对象组成的数组
  • 它返回一个新的promise对象,只有所有的promise都成功才成功,只要由一个失败了就直接失败

2.7 Promise.race()

  • 该方法属于Promise函数对象的,而不是属于实例对象的。
  • 它接收一个由Promise对象组成的数组参数
  • 它返回一个新的promise,第一个先完成的Promise的结果状态就是最终的结果状态

3、手写Promise

class Promise {
    //构造方法
    constructor(executor) {
        //初始化状态和结果
        let PromiseState = 'pending'
        let PromiseResult = null

        const context = this

        //用于存放回调函数
        let callbacks = []

        function resolve(value) {
            //判断状态是否为pending
            if (context.PromiseResult !== 'pending') return

            context.PromiseState = 'fulfilled'
            context.PromiseResult = value

            //执行成功的回调函数
            setTimeout(() => {
                context.callbacks.forEach(element => {
                    element.onResolved(value)
                });
            })
        }

        function reject(reason) {
            if (context.PromiseResult !== 'pending') return
            context.PromiseState = 'fulfilled'
            context.PromiseResult = reason

            //执行成功的回调函数
            setTimeout(() => {
                context.callbacks.forEach(element => {
                    element.onResolved(value)
                });
            })

        }
        try {
            executor(resolve, reject)
        } catch (e) {
            //抛出异常也可以改变Pormise的状态
            reject(e)
        }
    }

    //then方法
    then(onResolved, onRejected) {
        const context = this
        return new Promise((resolve, reject) => {
            //封装一个函数
            function callback(type) {
                //type为onResolved或者onRejected
                let result = type(context.PromiseResult)

                if (result instanceof Promise) {
                    result.then(() => {
                        resolve(result)
                    }, () => {
                        reject(result)
                    })
                } else {
                    resolve(result)
                }
            }

            if (context.PromiseState === 'fulfilled') {
                setTimeout(() => {
                    callback(onResolved)
                }, 0)
            }
            if (context.PromiseState === 'rejected') {
                setTimeout(() => {
                    callback(onRejected)
                }, 0)
            }

            //new Promise()时,里面的异步任务还没有执行完
            //故此时状态为pending
            if (context.PromiseState == 'pending') {
                context.callbacks.push({
                    onResolved: function () {
                        callback(onResolved)
                    },
                    onRejected: function () {
                        callback(onRejected)
                    }
                })
            }
        })
    }

    //catch方法
    //只捕获失败的回调函数
    catch(){
        return this.then(undefined,onRejected)
    }

    //添加resolve方法
    static resolve(value){
        return new Promise((resolve,reject)=>{
            if(value instanceof Promise){
                value.then((data)=>{
                    resolve(data)
                },(reason)=>{
                    reject(reason)
                })
            }else{
                return resolve(value)
            }
        })
    }

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

    //添加all方法
    static all(promises){
        //promises是一个由Promise对象组成的数组
        if(Object.prototype.toString.call(promises).slice(8,-1)!=='Array'){
            return 
        }
        return new Promise((resolve,reject)=>{
            let count = 0
            let valueList = []
            for (let i = 0; i < promises.length; i++) {
                promises[i].then((value) => {
                    count++
                    valueList[i] = value
                    //只有promises中所有的对象的状态都为成功时,才返回成功的实例对象
                    if (count === promises.length) {
                        resolve(valueList)
                    }
                },(reason)=>{
                    reject(reason)
                })
            }
        })
    }

    //添加race方法
    static race(promises){
    //promises是一个由Promise对象组成的数组
        if(Object.prototype.toString.call(promises).slice(8,-1)!=='Array'){
            return 
        }
        return new Promise((resolve,reject)=>{
            for (let i = 0; i < promises.length; i++) {
                promises[i].then((value) => {
                    //修改返回对象的状态为成功
                    resolve(value)
                }, (reason) => {
                    reject(reason)
                })
            }
        })
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值