zl程序教程

您现在的位置是:首页 >  其他

当前栏目

深度理解Promise状态变化_配合小Demo

状态 理解 深度 Demo 变化 Promise 配合
2023-09-27 14:22:48 时间

三种状态
pending
rejected
resolved

只能 pending 到 resolved
或者 pending 到 rejected

在new Promise的时候可以传入一个函数,第一个参数代表 resolve,第二个参数代表 reject,当然两个参数名可以自己定义。

看下面这个例子

//首先定义了一个 数组
        let subscribers = []
        //给数组添加元素的方法
        function addSubscriber(callback) {
            subscribers.push(callback)
        }
        // 普通函数
        function arr() {
            return 'arr返回'
        }
        //定义一个Promise
        let promiseTest = new Promise(resove => {
            //自动执行 打印111  最先打印的
            console.log(111)
            //将函数引用的形式push到数组里面
            addSubscriber(() => { resove(arr()) })

        })
        // let promiseTest = new Promise(resove => {
        //     addSubscriber(resove(arr()))
        // }) // 
        console.log(subscribers) //[f] 第一项是函数的引用
        console.log(promiseTest) //Promise处于 pending  状态 
        //调用数组的第一项 
        subscribers[0]()
        console.log(subscribers)
        //调用了  resolve()
        // 返回状态 resolved
        console.log(promiseTest)

在这里插入图片描述
我们在new Promise的时候并没有将 resolve()成功的结果返还出去,也没有将失败的结果返还出去,这个时候这个Promise对象一直处于Pending状态,直到我们调用了这个数组的第零项,状态从Pending编程了fulfilled(也就是resolved),表示成功了,在没调用函数之前,这个Promise一直处于挂起的状态,并没用返回,数组就是Promise状态收集器。

在看这个例子 我们只是稍微改动一下push到数组里面的东西

        let subscribers = []
        //给数组添加元素的方法
        function addSubscriber(callback) {
            subscribers.push(callback)
        }
        // 普通函数
        function arr() {
            return 'arr返回'
        }
        //定义一个Promise
        // let promiseTest = new Promise(resove => {
        //     //自动执行 打印111
        //     console.log(111)
        //     //将函数引用的形式push到数组里面
        //     addSubscriber(() => { resove(arr()) })
        // })
        let promiseTest = new Promise(resove => {
            addSubscriber(resove(arr()))
        }) // 
        console.log(subscribers)
        console.log(promiseTest) //Promise处于 resolved状态   

第一次打印promiseTest的时候他的状态已经变成了resolved了,不能存储状态。

token静默刷新
用户登录一段事件后,访问接口需要携带的token过期,但是用户一直在操作,直接跳转到登录页面很不友好,可以在用户不知道的情况下直接刷新token,如可以我们在axios相应拦截中判断。
在token静默刷新的时候,我们就可以这样存储Promise,等token刷新过后,在进行resolve(),返回数据。

这个参考了一位大佬的 前端Promise总结笔记
然后自己巧了一遍,理解了很多,收获了很多。

手写 Promise 代码
我在里面做了很多注释,大家可以看看,学习一下,我也是为了给自己加深印象~

 //首先 在Promise构造函数中 写两个方法
        //Promise参数是两个函数  定义状态
        //then函数 返回Promise 判断状态 回调 
        let data = 'xxx'
        let p = new Promise((resolve, reject) => { if (true) { resolve(data) } else { reject(data) } })
        p.then((res) => { }, (err) => { })
        //自定义函数Promise
        function Promise(executor) {
            //设置Promise 状态
            this.PromiseState = 'pending';
            //返回值 默认为null
            this.PromiseResult = null;
            //保存实例对象的this值
            const that = this;
            //定义callback属性,保存pending状态的回调函数
            // this.callback = {}
            this.callbacks = []
            //自定义resolve函数
            function resolve(data) {
                //控制改变状态次数 promise只能改变一次状态
                if (that.PromiseState !== 'pending') return
                that.PromiseState = 'resolved';
                that.PromiseResult = data;
                //异步任务成功后执行回调函数
                // if (that.callback.onResolved) {
                //     that.callback.onResolved(data)
                // }
                //异步任务成功后执行回调函数
                setTimeout(() => {
                    that.callbacks.forEach(item => {
                        item.onResolved(data)
                    })
                }, 0)

            }
            // 自定义reject函数
            function reject(data) {
                //控制改变状态次数 promise只能改变一次状态
                if (that.PromiseState !== 'pending') return
                that.PromiseState = 'rejected';
                that.PromiseResult = data;
                //异步任务失败后执行回调函数
                // if (that.callback.onRejected) {
                //     that.callback.onRejected(data)
                // }
                //异步任务失败后执行回调函数
                setTimeout(() => {
                    that.callbacks.forEach(item => {
                        item.onRejected(data)
                    })
                }, 0)

            }

            try {
                //同步调用  执行器函数
                executor(resolve, reject)
            } catch (err) {
                // throw err
                //更改Promise对象为失败状态
                reject(err)
            }

        }
        //封装then函数到原型链
        Promise.prototype.then = function (onResolved, onRejected) {
            let that = this
            //判断回调函数是否存在
            if (typeof onResolved !== 'function') {
                onResolved = value => value
            }
            if (typeof onRejected !== 'function') {
                onResolved = err => {
                    throw err
                }
            }
            return new Promise((resolve, reject) => {
                //重复代码封装
                function callback(type) {
                    try {
                        //获取回调函数执行的结果
                        let result = type(that.PromiseResult)
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(res => { resolve(res) }, err => { reject(err) })
                        } else {
                            //结果对象状态是 成功
                            resolve(result)
                        }
                    } catch (err) {
                        reject(err)
                    }
                }
                //Promise状态是resolved 走的 resolve函数
                if (this.PromiseState === 'resolved') {
                    // onResolved(this.PromiseResult)
                    callback(onResolved)
                }
                //Promise状态是rejected 走的 reject函数
                if (this.PromiseState === 'rejected') {
                    // onRejected(this.PromiseResult)
                    callback(onRejected)
                }
                //Promise状态为'pending'时,保存状态
                if (this.PromiseState === 'pending') {
                    // this.callback = {
                    //     onResolved,
                    //     onRejected
                    // }
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved)
                            // try {
                            //     //获取回调函数执行的结果
                            //     let result = onResolved(this.PromiseResult)
                            //     //判断
                            //     if (result instanceof Promise) {
                            //         //如果是Promise对象
                            //         result.then(res => { resolve(res) }, err => { reject(err) })
                            //     } else {
                            //         //结果对象状态是 成功
                            //         resolve(result)
                            //     }
                            // } catch (err) {
                            //     reject(err)
                            // }
                        },
                        onRejected: function () {
                            callback(onRejected)
                            // try {
                            //     //获取回调函数执行的结果
                            //     let result = onResolved(this.PromiseResult)
                            //     //判断
                            //     if (result instanceof Promise) {
                            //         //如果是Promise对象
                            //         result.then(res => { resolve(res) }, err => { reject(err) })
                            //     } else {
                            //         //结果对象状态是 成功
                            //         resolve(result)
                            //     }
                            // } catch (err) {
                            //     reject(err)
                            // }
                        }
                    })
                }
            })

        }
        //添加catch 方法
        Promise.prototype.catch = function (onRejected) {
            return this.then('', onRejected)
        }
        //添加 Promise.resolve() 方法
        Promise.resolve = function (value) {
            return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    value.then(res => { resolve(res) }, err => { reject(err) })
                } else {
                    reject(value)
                }
            })
        }
        //添加 Promise.reject() 方法
        Promise.reject = function (value) {
            return new Promise((resolve, reject) => {
                reject(value)
            })
        }
        //all方法
        //全部成功才返回成功res数组
        Promise.all = function (arr) {
            //添加变量
            let num = 0
            //存放成功结果的数组
            let arrList = []
            return new Promise((resolve, reject) => {
                for (let i = 0; i < arr.length; i++) {
                    arr[i].then(res => {
                        num++
                        arrList[i] = res
                        if (num == arrList.length) {
                            //只有全都成功的话 才返回正确的结果
                            resolve(arrList)
                        }
                    }, err => {
                        //失败
                        reject(err)
                    })
                }
            })
        }
        //race方法
        //请求多个,返回第一个成功等待额
        Promise.race = function (arr) {
            //根据promise状态值会改变一次 的特性 
            return new Promise((resolve, reject) => {
                for (let i = 0; i < arr.length; i++) {
                    arr[i].then(res => {
                        //成功
                        resolve(res)
                    }, err => {
                        //失败
                        reject(err)
                    })
                }
            })
        }

加油,打工人,争取年底给领导换辆车。