ES6新增特性——Promise

Posted Mary哎呀小龙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6新增特性——Promise相关的知识,希望对你有一定的参考价值。

一:为什么会出现?

1、场景一:在很多业务需求中,你需要通过ajax进行多次请求,而且每次请求返回的数据需要作为参数进行下一次的请求,于是会出现ajax层层嵌套问题。多个请求操作层层依赖,加上每一层还会有复杂的业务逻辑需要处理,使得代码可读性很差,不直观,难以维护和调试。

注:这种回调函数层层嵌套又称为回调地狱

//请求A
    $.ajax({
       success:function (res1) {
           //请求B
           $.ajax({
              success:function (res2) {
                 //请求C
                  $.ajax({
                     success:function (res3) {
                         ......
                         .......
                     }
                  })
              }
           })
       }
    })

2、场景二:如果请求C依赖于请求A和B的结果,但A和B之间互不依赖,如果仍写成A嵌套B,B嵌套C的形式,无疑是会消耗更多的等待时间。

故出现Promise对象来更合理和规范地处理异步操作。JS中所有代码都是单线程执行,如果必须是异步执行,可以通过回调函数实现

 

二:如何使用?

Promise对象是全局对象,可以理解为一个类。

Promise对象有三种状态:

                     pending:刚创建实例,表示初始化状态
                     fulfilled:resolve方法调用的时候,表示操作成功

                     rejected:reject方法调用的时候,表示操作失败

1、通过new生成一个实例,参数是一个匿名函数,其中有两个参数resolve,reject

   var pro = new Promise(function (resolve, reject) {
//pending状态
if (‘操作成功‘) { resolve();//resolve:处理异步操作执行成功后的回调函数 fulfiied状态 } else { reject();//reject:处理异步操作失败后的回调函数 rejected状态 } })

2、then()方法:用于处理操作后的处理程序

   pro.then(function (res) {
        //执行resolve回调函数
    }, function (error) {
        //执行reject回调函数
    })

3、catch()方法:处理操作异常的程序

  pro.catch(function (error) {
        //执行reject回调函数
    })

综合上面两个方法,一般用then方法处理操作成功的程序,catch用来处理操作异常的程序

  pro.then(function (res) {
        //执行resolve回调函数
    }).catch(function (error) {
        //执行reject回调函数
    })

完整示例:最后输出结果为:执行成功

   var pro = new Promise(function (resolve, reject) {
        //pending状态
        if (true) {
            resolve(‘执行成功‘);//resolve:处理异步操作执行成功后的回调函数  fulfiied状态
        } else {
            reject(‘执行失败‘);//reject:处理异步操作失败后的回调函数  rejected状态
        }
    })
    pro.then(function (res) {
        //执行resolve回调函数
        console.log(res)
    }).catch(function (error) {
        //执行reject回调函数
        console.log(error)
    })

三:如何解决回调地狱问题?

    var pro = new Promise(function (resolve, reject) {
        if (true) {
            resolve(‘执行成功‘);
        } else {
            reject(‘执行失败‘);
        }
    })
    pro.then(A)
       .then(B)
       .then(C)
       .catch(D)

    function A(res) {
        console.log(res) //执行成功
        return ‘给下一个B请求传参:成功执行A‘;
    }
    function B(res) {
        console.log(res) //给下一个B请求传参:成功执行A
        return ‘给下一个C请求传参:成功执行B‘;
    }
    function C(res) {
        console.log(res) //给下一个C请求传参:成功执行B
    }
    function D(error) {
        console.log(error)
    }

可以通过多个then方法进行链式操作,通过return方式给下一个执行回调函数传参,如上示例的结果是 

执行成功
给下一个B请求传参:成功执行A
给下一个C请求传参:成功执行B

四:如何解决场景二问题?

Promise.all()方法:当参数中的实例对象的状态都为fulfilled时,Promise.all()才会执行resolve函数

    var pro1 = new Promise(function (resolve, reject) {
       setTimeout(resolve(‘成功执行1‘),5000);
    });
    var pro2 = new Promise(function (resolve, reject) {
        setTimeout(resolve(‘成功执行2‘),1000);
    });
     Promise.all([pro1,pro2]).then(function (res) {
         console.log(res)
     })

pro1在1000ms以后成功进入fulfilled状态,但此时Promise.all还是不会有行动,需要等到pro2进入到fulfilled状态时,才会进入then方法,故5000ms以后执行结果为:

[

‘成功执行1‘,
‘成功执行2‘

]

类似的方法还有Promise.race()方法,参数为Promise实例,只要有一个状态发生改变,不管是成功fulfiied还是失败rejected状态,就会有返回,其他实例再有变化也不会再处理了。

   var pro1 = new Promise(function (resolve, reject) {
       setTimeout(resolve,5000,‘成功执行1‘);
    });
    var pro2 = new Promise(function (resolve, reject) {
        setTimeout(reject,1000,‘失败执行2‘);
    });
     Promise.race([pro1,pro2]).then(function (res) {
         console.log(res)
     }).catch(function (error) {
         console.log(error)
     })

执行结果为:

失败执行2

以上是关于ES6新增特性——Promise的主要内容,如果未能解决你的问题,请参考以下文章

ES6知识笔记

ES6新特性之 promise

ES6新特性之 promise

ES6 新增的一些特性

ES6新特性:Javascript中内置的延迟对象Promise

es6,promise,generator,next,yield与koa