ES6 Promise基础

 一、promise是什么?

  • promise是js中进行异步编程的新的解决方案(传统的方案是使用回调函数)
  • promise是一个构造函数
  • promise对象可以用来封装一个异步操作并且可以获取其成功/失败的结果值

异步操作有比如:数据库操作,定时器,Ajax,fs文件操作

二、为什么要使用promise?

支持链式调用,可以解决回调地狱问题

1.什么是回调地狱?

  btn1.addEventListener("click",()=>{
            btn2.addEventListener("click",()=>{
                btn3.addEventListener("click",()=>{
                    console.log("hello world")
                })
            })
        })

即:回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数执行的条件;

缺点:不便于阅读,不便于异常处理

解决方案:promise链式调用,指定回调函数的方式更加灵活

promise案例:

模拟异步操作回调:

需求:张三向多个女孩进行告白,但是向第二个女孩告白前,需要根据第一个女孩的回应,判断是否向第二个女孩告白,如果第一个女孩同意,则不向第二个女孩告白;我们将定义定时器和随机数模拟;当随机数小于0.3代表同意告白

传统的嵌套回调函数方式:

        function sendLove(nvhai, callback) {
            console.log(`张三向女孩${nvhai}告白了`)
            setTimeout(() => {
                if (Math.random() < 0.3) {
                    callback(true)
                } else {
                    callback(false)
                }
            }, 1000)
        }

        sendLove('1', function(result) {
            if (result) {
                console.log("女孩1答应le,梅老师很高兴")
            } else {
                console.log("女孩1没答应")
                sendLove('2', function(result) {
                    if (result) {
                        console.log("女孩2答应le,梅老师很高兴")
                    } else {
                        console.log("女孩2没答应")
                        sendLove('3', function(result) {
                            if (result) {
                                console.log("女孩3答应le,梅老师很高兴")
                            } else {
                                console.log("张三心灰意冷")
                            }
                        })
                    }
                })
            }
        })

//张三向女孩1告白了
//05.html:28 女孩1没答应
//05.html:14 张三向女孩2告白了
//05.html:33 女孩2没答应
//05.html:14 张三向女孩3告白了
//05.html:36 女孩3答应le,张三很高兴

显而易见这样代码非常不利于阅读;

promise形式实现:

  •     只要有一件异步事情发生时,就会存在两个阶段 unsettled未决阶段和settled已决阶段
  •     事情总是从未决阶段走向已决阶段,并且未决阶段拥有控制通往已决阶段的能力,可以决定事情最终走向的结果

promise将程序分为三种状态 pending resolved rejected

  •     pending 等待  处于unsettled阶段,表示事情还在等待最终的结果
  •     resolved 已处理  处于setteled阶段,表示事情已经出现结果,并且可以按照正常的逻辑进行下去的结果
  •     rejected 已拒绝 处于setteled阶段,表示事情已经出现结果,并且不可以按照正常的逻辑进行下去的结果
  •     把事情从pending状态推向resolved状态的过程中,可能会传递一些数据,这些数据为真实有效数据
  •     把事情从pending状态推向rejected状态的过程中,可能会传递一些数据,这些数据为错误信息
  •     无论是在哪个阶段还是那个状态,都是不可逆

当事情已经到达已决阶段后,通常用结果数据做一些后续处理,不同的已决结果,可能造成不同的后续处理

  •     resolved 后续处理表示为thenable
  •     rejected 后续处理表示为catchable 
  •     后续处理可能有多个,因此会形成任务队列,这些后续处理会按照顺序当到达对应的状态时会依次执行

用法:

Promise对象是一个构造函数,用来生成Promise对象

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject

let pro = new Promise((resolve, reject) => {})
  • resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”
  • reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”

Promise实例方法:

  • then()方法返回的是一个新的Promise实例,也就是promise能链式书写的原因
  • catch()用于指定发生错误时的回调函数
  • finally()用于指定不管 Promise 对象最后状态如何,都会执行的操作
         function sendLove(nvhai) {
            return new Promise((resolve, reject) => {
                console.log(`张三向女孩${nvhai}告白了`)
                setTimeout(() => {
                    if (Math.random() < 0.3) {
                        resolve(true) //同意
                    } else {
                        resolve(false) //不同意
                    }
                }, 1000)
            })
        }
        sendLove('1').then(res => {
            if (res) {
                console.log("女生1同意了")
                return undefined
            } else {
                console.log("女生1没同意了")
                return sendLove('2')
            }
        }).then(res => {//链式调用,根据上一次的结果,判断下一次如何执行
            if (res === undefined) {
                return
            }
            if (res) {
                console.log("女生2同意了")
            } else {
                console.log("女生2没同意了")
                return sendLove('3')
            }
        }).then(res => {
            if (res === undefined) {
                return
            }
            if (res) {
                console.log("女生3同意了")
            } else {
                console.log("都被拒绝了")
            }
        });

注意点:

  1. 未决阶段的处理函数时同步的,会立即执行

  2. 已决阶段的状态只能有一个,resolve和reject不能同时使用,如果同时使用则只有第一个会执行

  3. thenable和catchable函数是异步的,加入至微队列中

  4. pro.then方法可以添加两个参数thenable和catchable,pro.catch方法可以是一个参数catchable

  5. 在未决阶段的处理函数中,如果发生未捕获的错误,会将状态推向rejected状态,并且会被catchable所捕获

  6. 如果前面的promise的后续处理,返回一个新的promise,则把新的promise的值和状态给then方法返回值。 如果前面的promise的后续处理,用return关键字进行返回,则then方法返回值的状态为resolve,值为返回值 用未捕获的错误进行返回,则then方法返回值的状态为reject,值为错误

promise静态方法

*resolve()静态方法创建promise成功的实例
*reject()静态方法创建promise失败的实例
*all(arr)静态方法返回一个promise对象,当数组里面的所有promise对象的状态都为resolve, 则新的promise对象的状态为resolve,值为所有promise返回值的数组作为成功回调的返回值。反之有一个rejected状态,则新的promise对象的状态为rejected,把第一个触发失败的promise对象的错误信息作为它的失败错误信息
*race(arr)静态方法方法返回一个 promise,一旦数组中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
allSettled()静态方法方法返回一个在所有给定的promise都已经resolve或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。
any()静态方法只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 

        //all
        let arr = [];
        function sendLove(i) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    if (Math.random() < 0.5) {
                        console.log(i, "失败")
                        reject(i)
                    } else {
                        console.log(i, "成功")
                        resolve(i)
                    }
                }, Math.floor((Math.random() * 5000) + 1000))
            })
        }
        for (let i = 0; i < 10; i++) {
            arr.push(sendLove(i))
        }
        console.log(arr)
         
        //race返回一个状态改变最快的promise
        Promise.race(arr).then(data => {
            console.log(data)
        }, err => {
            console.log(err)
        })

三、async和await关键字

async 简化promise创建

充当函数修饰符,用于修饰函数声明或函数表达式,放在函数的开始位置,被修饰的函数一定会返回一个promise对象

await 相当于then方法的

await关键字必须放在被async修饰的函数里面,作用是相当于then方法中thenable

async和await关键字注意点

  • 如果await关键字后面跟的不是一个promise对象,则直接输出await关键字后面的内容
  • 如果async函数中有错误时,可以使用trycatch区捕获错误
        async function test() {
            // return 1
            throw 2
        }
        test().then(data => {
            console.log(data)
        }, err => {
            console.log(err)
        });
        
        (async function() {
            try {
                let a = await test()
                console.log(a)
            } catch (error) {
                console.log(error)
            }
        })()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值