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

简介: 本文通过代码示例深入探讨了JavaScript中Promise对象的三种状态(pending、rejected、resolved)及其变化过程,解释了在什么情况下Promise会从pending状态变为resolved或rejected状态,并演示了如何通过Promise的状态管理异步操作。

三种状态
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)
                    })
                }
            })
        }

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

目录
相关文章
|
6月前
|
小程序
在uniapp中监听globalData中的值变化
在uniapp中监听globalData中的值变化
283 0
|
2月前
|
存储 前端开发 JavaScript
node中循环异步的问题[‘解决方案‘]_源于map循环和for循环对异步事件配合async、await的支持
本文探讨了在Node.js中处理循环异步操作的问题,比较了使用map和for循环结合async/await处理异步事件的差异,并提供了解决方案。
35 0
|
3月前
|
JavaScript 前端开发 Java
v-if和v-show的区别?使用场景?v-if状态改变调用钩子函数的示例
这篇文章详细阐述了Vue中`v-if`和`v-show`指令的共同点、区别、使用场景以及它们在组件和普通元素上附属时的不同表现,并通过示例展示了状态改变时对钩子函数调用的影响。
v-if和v-show的区别?使用场景?v-if状态改变调用钩子函数的示例
|
3月前
|
JavaScript 前端开发 API
揭秘Node.js如何轻松访问API:一个示例足以改变你的开发视角!
【8月更文挑战第21天】在现代Web开发中,API是软件间通信的关键。Node.js以其高效性,在API访问上独具优势。本文通过示例展示如何用Node.js访问API。首先确保已安装Node.js,然后使用npm安装`axios`库。创建`api_example.js`文件,并编写代码以访问JSONPlaceholder API获取数据。成功时,响应数据会输出至控制台;若失败,则打印错误。此示例展示了Node.js结合`axios`访问API的便捷性及高效性,为初学者提供快速入门指南。
32 0
|
6月前
|
前端开发 Java
Promise--代码实现-- ajax 传统方式和 promise 方式和 promise 代码优化/重排 方式的对比--综合代码示例
Promise--代码实现-- ajax 传统方式和 promise 方式和 promise 代码优化/重排 方式的对比--综合代码示例
55 0
Vue3新增的两个生命周期分析解释【onRenderTracked()状态跟踪和onRenderTriggered() 状态触发】
Vue3新增的两个生命周期分析解释【onRenderTracked()状态跟踪和onRenderTriggered() 状态触发】
|
前端开发
前端 window.print() 打印方案、优化策略总结(一)
前端 window.print() 打印方案、优化策略总结(一)
814 0
前端 window.print() 打印方案、优化策略总结(一)
|
JSON 前端开发 JavaScript
前端 window.print() 打印方案、优化策略总结(二)
前端 window.print() 打印方案、优化策略总结(二)
455 0
|
前端开发
前端学习案例15-promise的理解方式&调用机制2
前端学习案例15-promise的理解方式&调用机制2
77 0
前端学习案例15-promise的理解方式&调用机制2
|
前端开发
前端学习案例14-promise的理解方式&调用机制1
前端学习案例14-promise的理解方式&调用机制1
74 0
前端学习案例14-promise的理解方式&调用机制1