ES6 promise详解

ES6 Promise

1.什么是promise?

ES6 中一个非常重要和好用的特性就是Promise

  • promise 到底是做什么的呢?

    promise 是异步编程的一种解决方案。

  • 那什么时候我们回来处理异步事件呢?

    1.一种很常见的场景就是网络请求
    2.我们分装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的3+4 = 7一样将结果返回。
    3.所以我们往往会传入另外一个函数,在数据请求成功的时候,将数据同过传入的函数回调出去。
    4.如果知识一个简单的网络请求,那么这种方案就不会给我们带来很大的麻烦。

    但是当网络请求非常复杂时,就会出现回调地狱。

举一个案例,说明promise的好处!

案例需求:
    1.ajax请求一个data1,包含一个url1
    2.url中包含下一个请求的url2
    3.url2中包含下一个请求的url3
    4.url3中包含一个下一个请求的url4
    5.url4中返回最终数据data4

    $.ajax('url1',function(data){
        $.ajax(data1['url2'],function(data2)){
            $.ajax(data2['url3'],function(data3)){
                $.ajax(data3['url4'],function(data4)){
                    console.log(data4)
                }
            }
        }
    })

这样看来并没有什么问题。
如果我每一次请求都有100行代码处理数据,这样代码看起来就会很乱,而且难以维护!

2.promise的基本语法

  • 最基本的promise使用
 //1.参数是两个函数 resolve  和  reject 而resolve 和 reject本身又是函数
    new Promise((resolve, reject) => {
         setTimeout(() => {
             console.log('hello promise')
         },1000)
     })
  • 在promise中执行多个异步操作
 
    //2.如果说我要在promise中执行多个异步操作
     new Promise((resolve, reject) => {
         setTimeout(() => {
             console.log('第一次请求');
             setTimeout(() => {
                 console.log('第二次请求');
                 setTimeout(() => {
                     console.log('第三次请求');
                 },1000)
             },1000);
         },1000)   
     })

    //这种在执行完1后执行2再执行3,就出现了我们所说的回调地狱。

    //所以我们希望能将里面的多个请求提取出来

3.promise的三种状态

 首先,往我们开发中有异步操作的时候,就可以给异步操作包装一个Promise
        异步操作之后会有三种状态


           1.pendding()  等待状态,比如正在进行网络请求,就处于该状态,或者定时器还没有到时间

           2.fulfill()   满足状态,当我们主动回调了resolve(),就处于这中状态,并且会回调then()

           3.reject()    拒绝状态,当我们主动回调了rehect(),就处于这种状态,并且会回调catch()

promise解析:  当你new完promise的时候就会传回来两个参数,resolve和reject,同时那两个参数也是函数。
    		  new  -> (构造函数)  
     			1.保存一些状态信息。
                2.执行传入的函数。
                3.执行这个回调函数的时候会传入两个参数resolve和reject,同时这两个参数又是函数。

4. 运用promise来处理多个异步操作 链式编程

  • promise处理多个异步操作
new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve();   //传入resolve(),可以调用.then() 执行.then()
        },1000)
    }).then(()=>{
        console.log('第一次请求');
        return new Promise((resolve, reject)=>{
            setTimeout(() => {
               resolve(); 
            },1000)
        }).then(() => {
            console.log('第二次请求');
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve()
                },1000)
            }).then(()=>{
                console.log('第三次请求');
            })
        })
    })
  • promise关于resolve和reject的优化写法
    另外一种写法   直接在.then()函数中传入两个函数参数,resolve时执行第一个,reject执行第二个
             new Promise((resolve, reject) => {
                 setTimeout( ()=> {
                     // resolve('resolve message');
                     reject('error message');
                 },1000)
             }).then(res =>{
                 console.log(res)
             },data=>{
                 console.log(data)
             })
//系统默认第一个函数为调用resolve时执行的函数,第二个函数为执行reject时执行的函数
  • promise根据需求处理数据实例:
          需求:请求回来 aaa - > 自己处理
                处理 aaa111
                处理 aaa111222

                new Promise((resolve, reject) => {
                    setTimeout(() => {
                        resolve('aaa')
                    },1000)
                }).then(res => {
                    console.log(res,'第一行的执行结果')
                    return new Promise((resolve, reject) => {
                        resolve(res + '111')
                    })
                }).then(res => {
                    console.log(res,'第二次执行结果');
                    return new Promise((resolve, reject) => {
                        resolve(res + '222')
                    })
                }).then(res => {
                    console.log(res,'第三次处理的结果');
                })
  • promise优雅的处理返回来的数据和reject()的再理解
promise优雅的处理请求回来的数据
        
         new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('xiyounet')        //不推荐我们在这里处理请求回来的数据
            })
        }).then((data)=>{
            console.log(data); //xiyouney  //通过参数传入到.then()中去处理
            console.log(data + 2019); //xiyounet2019
        })


    这时候我们可以看到promise传入的参数中还有一个reject,那么reject又是来做什么的?
    类似于ajax当我们处理请求成功的时候我们需要执行sucess函数,失败执行error,reject就是当我们处理请求失败的时候执行
    简单的实例“:
        new Promise((resolve, reject) => {
            setTimeout(() => {

             //  resolve(); //这里调用resolve()   就会执行.then()
                reject('error message');   //这里调用reject()   就会执行.catch()
            })
        }).catch((data)=>{
            console.log("我是执行的reject函数:"+data)
        })

5.promise的优化写法

  • 省略 new promise的优化写法
                new Promise((resolve, reject) => {
                    setTimeout(() => {
                        resolve('aaa')
                    },1000)
                }).then(res => {
                    console.log(res,'第一行的执行结果')
                    return Promise.resolve(res + '111')
                    
                }).then(res => {
                    console.log(res,'第二次执行结果');
                    return Promise.resolve(res + '222');
                    
                }).then(res => {
                    console.log(res,'第三次处理的结果');
                })

               // 处理结果显示也是 o的   解释;  内部给我们提供了 promise.resolve() 的方法
  • 再一步省略promise.resolve()
 new Promise((resolve, reject) => {
                    setTimeout(() => {
                        resolve('aaa')
                    },1000)
                }).then(res => {
                    console.log(res,'第一行的执行结果')
                    return (res + '111')
                    
                }).then(res => {
                    console.log(res,'第二次执行结果');
                    return (res + '222');
                    
                }).then(res => {
                    console.log(res,'第三次处理的结果');
                })


                //处理结果也是o的   解释:内部给我们包装了promise

6.当请求中有错误时抛出错误

  • 当有一步错误时我们也可以抛出错误
         new Promise((resolve, reject) => {
                    setTimeout(() => {
                        resolve('aaa')
                    },1000)
                }).then(res => {
                    console.log(res,'第一行的执行结果')
                    return Promise.reject('error message');
                    
                }).then(res => {
                    console.log(res,'第二次执行结果');
                    return Promise.resolve(res + '222');
                    
                }).then(res => {
                    console.log(res,'第三次处理的结果');
                }).catch(err => {
                    console.log(err)
                })
                
                //当执行了Promise.reject时,就会直接调用catch(),
                //打印结果为:  aaa第一行的执行结果    和   error  message


                //我们也可以通过throw的方法手动抛出错误
                 new Promise((resolve, reject) => {
                     setTimeout(() => {
                         resolve('aaa')
                     },1000)
                 }).then(res => {
                     console.log(res,'第一行的执行结果')
                     // return Promise.reject('error message');
                     throw 'error message'
                    
                 }).then(res => {
                     console.log(res,'第二次执行结果');
                     return Promise.resolve(res + '222');
                    
                 }).then(res => {
                     console.log(res,'第三次处理的结果');
                 }).catch(err => {
                     console.log(err)
                 })


                //这样也是ok的   简直太帅了不要


7.promise.all()方法的使用

promise.add() 方法的使用 当一个页面需要所有的网络请求都完成时显示,只有两个结果都请求完成才算成功,这个时候我们使用ajax很难判断哪个请求先完成,以及是否处理代码。

  • promise.all() 方法实例

                 Promise.all([
                     new Promise((resolve, reject) => {
                         setTimeout(() => {
                             resolve({name:'kjh',age:20})
                         },1000)
                     }),
                     new Promise((resolve, reject) => {
                         setTimeout(() => {
                             resolve({hobby:'pingpang',wifi:'xiyounet'})
                         },2000)
                     })
                 ]).then(result => {
                     console.log(result[0], result[1]);   
                 })

                //3s中后完成两个请求,一起返回数据

你可能感兴趣的:(es6,es6,promise)