四、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>

新代码(使用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>

总结:上面的使用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.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 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']

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)

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)
            })

二、异步链式操作

需求:先获得到用户的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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值