• 四、JavaScript Promise[基础、异步链式操作]


    一、Promise

    1.基础用法

    1.1 案例

    解释:JavaScript 中存在很多异步操作,Promise 将异步操作队列化按照期望的顺序执行,返回符合预期的结果。可以通过链式调用多个 Promise 达到我们的目的

    旧代码(没有使用Promise):此代码需要嵌套调用,写起来很难维护。

        <script>
            setTimeout(()=>{
                console.log(1)
                setTimeout(()=>{
                    console.log(2)
                    setTimeout(()=>{
                        console.log(3)
                    })
                },10)
            },10)
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    新代码(使用Promise):链式结构使用方便

        <script>
            new Promise((resolve)=>{
                setTimeout(()=>{
                    console.log(1)
                    resolve('success')
                },1000)
            }).then(()=>{
                setTimeout(()=>{
                    console.log(2)
                },1000)
            }).then(()=>{
                setTimeout(()=>{
                    console.log(3)
                },1000)
            })
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    总结:上面的使用Promise打印出 1 2 3,但其实并非按照你想的那样去执行,需要知道原理便于下面的学习,阅读JavaScript任务管理

    1.2 基础

    解释:Promise无法让异步程序成为同步程序,它只是让异步程序后面紧跟一个微任务,以便于异步完成之后执行你想要的操作(被放到微任务),Promise 包含pending、fulfilled、rejected三种状态

    • pending 指初始等待状态,初始化 promise 时的状态
    • resolve 指已经解决,将 promise 状态设置为fulfilled
    • reject 指拒绝处理,将 promise 状态设置为rejected
    1.2.1 then

    解释:resolve(其实它是第一个参数,可以随便命名)配合的就是then****,当程序碰到resolve才会进行then操作(没有的话then根本不会被执行),then无需resolve反馈(写上还会报错),默认就是(promise 状态设置为fulfilled)(可以自己设置返回的Promise对象),代码如下

            new Promise((resolve,reject)=>{
                console.log(123)
                resolve('fl')
            }).then(()=>{
                console.log(2)
            })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1.2.2 catch

    解释:reject(其实它是第二个参数,可以随便命名)配合使用的就是catch,当程序碰到reject才会进行catch操作,代码如下

            new Promise((resolve,reject)=>{
                console.log(123)
                reject('fl')
            }).then(()=>{
                console.log(2)
            }).catch((a)=>{
                console.log(a)
            })
    // 结果
    123
    fl
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1.2.3 finally

    解释:无论状态是resolve 或 reject 都会执行此动作,finally 与状态无关

    2.扩展用法

    1.all

    • all里面放的是可迭代的数组
    • 任何一个 Promise 执行失败就会调用 catch方法
    • 适用于一次发送多个异步操作
    • 全部都成功后返回 promise 结果的有序数组

    应用:通过其全部完成后才返回的特性,可以通过其放几个异步请求,当在加载时显示加载动画,全部加载完成后,再设置显示页面

            var a = new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve('fl')
                }, 5000)
            })
            var b = new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve('fl')
                }, 1000)
            })
            Promise.all([a, b])
                .then(results => {
                    console.log(results);
                })
    // 结果(这个会等5秒才执行(最长所需要的时间))
    ['fl', 'fl']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.allSettled

    区别(同all):其不关心是否全部成功,其永远会成功返回结束(而all遇到错误会报错)

            var a = new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve('fl')
                }, 5000)
            })
            var b = new Promise((resolve, reject) => {
                setTimeout(() => {
                    reject('fl')
                }, 1000)
            })
            Promise.allSettled([a, b])
                .then(results => {
                    console.log(results);
                })
    // 结果
    [{}, {}]
    // 展开后
    0
    : 
    {status: 'fulfilled', value: 'fl'}
    1
    : 
    {status: 'rejected', reason: 'fl'}
    length
    : 
    2
    [[Prototype]]
    : 
    Array(0)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    3.race

    区别(同all):当其中某一个Promise(最快的)返回后,其race就会结束,(其它Promise还会再执行,只是不会把值反馈到race里面)

    应用:数组里面只放二个Promise(一个是异步,一个是定时器),当其获取时间过长时,提示用户

            // 假设a是异步请求
            var a = new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log(1)
                    resolve('fl')
                }, 5000)
            })
            // 假设b是当a超时后反馈的定时器(超过两秒就超时)
            var b = new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log(2)
                    reject('fl')
                }, 2000)
            })
            Promise.race([a, b])
                .then(results => {
                    console.log(results);
                }).catch((h)=>{
                    alert(h)
                })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    二、异步链式操作

    需求:先获得到用户的ID,再通过用户ID获取到用户名,再通过ID和用户名再获取用户的身份信息(需要先获取用户ID,再获取用户名,再获取用户身份信息(前后顺序不能改变))

    代码实现:

        <script>
            var aa = 1, bb = 1, cc = 1;
            function a() {
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        aa = 9;
                        console.log(1)
                        resolve('1')
                    }, 5000)
                })
            }
            function b() {
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        bb = aa + 10;
                        console.log(bb)
                        resolve('2')
                    }, 7000)
                })
            }
            function c() {
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        cc = bb + aa + 11;
                        console.log(cc)
                        resolve('3')
                    }, 5000)
                })
            }
    
            a().then(() => {
                return b();
            }).then(() => {
                return c();
            }).then(() => {
                console.log('ok')
            })
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
  • 相关阅读:
    Java SqlSessionFactoryBean.setMapperLocations方法代码示例
    VAE学习总结
    Go语言的IO库那么多纠结该如何选择
    玩机搞机---脱离电脑 用手机给手机刷机 解锁bl 获取root的方法教程
    android 平台 c 程序编译
    四元数和旋转矩阵两种方式对旋转向量进行更新结果对比
    慢下来的互联网医疗要等下一阵风?
    JDK中自带的JVM分析工具
    学生DW静态网页设计——html+css+javascript+jquery+bootstarp马尔代夫旅游响应式网站
    HTTP 结构概述
  • 原文地址:https://blog.csdn.net/weixin_46765649/article/details/127672836