es6——Promise

Promise的常用的用法

搬运es6入门一书中所述:
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

回调地狱

先见识一下回调地狱

/*
 *	实际开发项目中经常会有这种需求,在a请求结束后,拿到a的一些结果,然后根据a结果中的一些数据当做参数请求b
 *	当多个异步任务需要顺序执行时,难免会出现这种写起来较为难受的代码
 */
 $.ajax({
       url: './aa.json',
       dataType: 'json',
       success(data1) {
           $.ajax({
               url: './bb.json',
               dataType: 'json',
               success(data2) {
                   $.ajax({
                       url: './aa.json',
                       dataType: 'json',
                       success(data3) {
                           console.log(data1, data2, data3)
                       }
                   })
               }
           })
       }
   })

Promise

es6将Promise写进了其语言标准,它最早由社区提出和实现

基本用法

ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。
下面代码创造了一个Promise实例

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

		// resolve:    英文意思为解决,即成功了会触发
        // reject:     英文意思为拒绝,即失败了会触发
        let prom = new Promise(function (resolve, reject) {
            $.ajax({
                url: './aa.json',
                dataType: 'json',
                success(data) {
                    resolve(data)
                },
                error(res) {
                    reject(res)
                }
            })
        })

        //  不论promise是成功还是失败了,只要有结果都会进入then,then中会有两个函数,
        // 	第一个函数代表成功,第二个函数代表失败;需注意,第二个函数参数为可选
        prom.then(function (data) {
            alert('success')
            console.log(data)
        }, function (res) {
            alert('default')
            console.log(res)
        })

Promise.all()

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。其接收的参数是个数组,成功后返回的也是个数组,失败后返回的是错误信息

// 要等待promise数组中所有的操作完成后,进入then
        Promise.all([
            $.ajax({ url: './aa.json', dataType: 'json' }),
            $.ajax({ url: './bb.json', dataType: 'json' }),
            $.ajax({ url: './cc.json', dataType: 'json' })
        ]).then(function (arr) {//  所有成功后返回个数组
            alert('success')
            console.log(arr)
        }, function (res) {//   只要有一个失败就失败,进入失败
            alert("fail");
            console.log(res)
        })

        //  缺陷:没有任何逻辑情况下,可以用all,万一第二个请求需要第一个请求返回的结果,就无法适用了;万一一个请求接口失败就全部GG

利用Promise解决回调地狱方法

方法1

有了Promise之后,我们可以将普通的ajax方法封装为Promise方法

 		/*  
         *  注意request函数,函数构造了Promise对象并将其return出来,这是帮助我们书写可读性高的异步代码的关键。 
         *  之后,我们可以使用Promise的链式调用方式来处理请求
         */
        let request = function (url) {
            return new Promise((resolve, reject) => {
                $.ajax({
                    url: url,
                    dataType: 'json',
                    success(data) {
                        resolve(data)
                    },
                    error(res) {
                        reject(res)
                    }
                });
            })
        }

        //  避免回调地狱方法1
        request('./aa.json').then(function (data1) {
            alert('第一个请求成功了,继续第二个请求')
            console.log(data1)
            return request('./bb.json')
        }).then(function (data2) {
            alert('第二个请求成功了,继续第三个请求')
            console.log(data2)
            return request('./cc.json')
        }).then(function (data3) {
            alert('第三个请求成功了')
            console.log(data3)
        })

注意每一个then的参数函数内我们又调用了个request函数,即返回了一个Promise对象,这也是Promise的链式调用的关键所在。

说人话即可理解为:then() return的也是一个promise。所以就可以继续.then(),接收上一个.then() return的值;有return值 就可以继续.then()

此方法缺陷:
Promise函数改变了之前回调地狱的写法,但是在根本上还是函数套函数,看起来不是那么的美观
Promise一经执行,无法中断,除非抛出异常
在Promise外部无法通过try/catch的方式捕获Promise内部抛出的异常。

方法2

promise结合async和await使用,可发挥巨大威力;

可以延展的说一下async/await。尽管这是一个 ES7 标准内的语法。 async/await可以将Promise代码组织的更像同步代码一样,其书写方式就和之前写同步代码一样,只是需要加上相应关键字。 例如:

		//  避免回调地狱方法2
        //  async声明此函数是async函数,说人话就是里面可包含异步操作
        async function show() {//   await表面是同步的,一行代码执行完继续执行第二行,但是经过async后,性能其实是异步的,不用担心性能
            // let data = await Promise对象
            let data1 = await $.ajax({ url: './aa.json', dataType: 'json' })
            debugger
            console.log('1欧了,继续2')
            let data2 = await $.ajax({ url: './bb.json', dataType: 'json' })
            let data3 = await $.ajax({ url: './cc.json', dataType: 'json' })

            console.log(data1, data2, data3)
        }

        show()

上述代码在控制台中打断点可看出是同步执行的,data1返回结果后才会继续进行data2,data2返回结果后继续执行data3;
又如下面的代码

		async function show() {//   await表面是同步的,一行代码执行完继续执行第二行,但是经过async后,性能其实是异步的,不用担心性能
            // let data = await Promise对象
            let data1 = await $.ajax({ url: './aa.json', dataType: 'json' })
            if (data1.aa < 9) {
                alert('执行2')
                let data2 = await $.ajax({ url: './bb.json', dataType: 'json' })
            } else {
                alert('执行3')
                let data3 = await $.ajax({ url: './cc.json', dataType: 'json' })
            }

            console.log(data1, data2, data3)
        }

        show()

        //  promise 单独用一般,只有结合async和await才会异常好用,async和await有一种叫法,叫做语法糖
        //  虽然async和await给人的感觉是同步的,但是经过计算机编译后,它自己执行还是异步的,没有性能的消耗
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值