promise,与async函数

一、Promise

1.1 回顾回调函数:

1.概念:

 一个函数在另一个函数调用(一个函数传递另一个函数做参数使用)

2.异步和同步:

  js,在主线程上面,先执行同步任务,再执行异步任务,等主线程上的同步任务全部完成之后,回到异步队列进行查找,将异步队列里面的任务放到执行栈中,继续遵循规则;

  同步:排队执行;

  异步:不会阻塞后面代码执行;

   

1.2 promise

1)概念: 解决异步编程的方法

2)语法: 需要new 实例化;resolve返回的是成功状态值;reject返回的是失败状态值;

 接收失败状态的区别:

            1. catch直接捕获reject返回的失败状态值;

            2.then里面有第二个参数err,捕获就是失败状态值;

          区别:使用catch,不仅可以接收reject返回的失败状态值,也可以捕获在成功状态时,处理业务逻辑时报的错;then里面的第二个回调函数来接收;只能捕获reject返回的失败状态的值

 

3)特点:

             1. 三种状态:进行时,已成功,已失败

             2. 两种状态转换:进行时=》已成功;进行时=》已失败

4promise一旦创建就会立即执行(同步任务);

       调用resolvereject执行异步任务;状态也会发生改变:由进行中=》已成功或者是已失败;

    

      console.log(1);

        let p1 = new Promise((resolve, reject) => {

            console.log('promise'); // 同步任务  进行中

            resolve("success");

        });

        p1.then(res => {

            console.log(res) // 异步任务  微任务

        });

        console.log(2); // 最终打印出的结果先后顺序为 1, promise, 2, success

 

 

5)链式调用:从第二个then开始,拿的是上一个then return之后的返回值;

   案例1

   

      function fn(num) {

            return new Promise(resolve => {

                setTimeout(() => {

                    resolve(num)

                }, 1000);

            });

        };

        console.log(fn());

        fn(10).then(res => {

            console.log(res)

            return fn(++res)

        }).then(res => {

            console.log(res)

            return fn(++res)

        }).then(res => {

            console.log(res)

        });

 

6)解决回调地狱:

ajax请求成功与失败结果与promise本身的成功与失败的状态没有必然的联系

  

      function myAjax({

            type = "get",

            url,

            data = {}

        }) {

            return new Promise((resolve, reject) => {

                $.ajax({

                    type,

                    url,

                    data,

                    success: function(response) {

                        resolve(response.result.data);

                    }

                })

            });

        };

 

7)Promise.all Promise.race

Promise.all() 做并发处理,等所有的请求有了返回值之后,同一返回,返回的是一个数组;

Promise.race() 获取的是请求速度最快的值;(设置定请求时间,超过500ms的时候,提示用户请求超时。)

 

        let p1 = new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve('123');
            },5000);
        });
        let p2 = new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve('456');
                // reject('error');
            },1000);
        }).catch(err=>{
            console.log(err);
        }) ;
        Promise.all([p1,p2]).then(res=>{
            console.log(res);     //  ["123", "456"]  等5s后才会打印出
        });
        Promise.race([p1,p2]).then(res=>{
            console.log(res);     //   456 
        });        

 

 

 

 

错误捕获两种方法

直接在all方法后面直接写catch;只返回失败状态值,其他请求成功状态的值,无法返回;

谁返回的失败状态,谁来处理;既可以接收本身自己的失败状态值,其他请求成功状态的值,也不受影响

 

二、async函数:

1.Async 函数是Generator函数语法糖;

2.语法:

1) function前面加async关键字;

    箭头函数async关键字放在形参的前面;

2) 返回的是一个promise对象;

3) await 等待:

  1.await后面的值,不会返回到函数的外部;

  2.async函数内可以有多个await

  3.await等待的是后面表达式的结果值;注意,如果是promise对象,默认情况下只返回成功状态值;

  4.await有阻塞后面代码执行作用,await后面的表达式有结果之后,下面的代码才可以执行;

  5.async函数内部是同步任务;不影响主线程上任务的执行顺序;

 

   let p1 = new Promise(resolve => {

            setTimeout(() => {

                resolve("p1")

            }, 3000);

        });

        console.log("fn start");

        async function fn() {

            console.log(1);

            let a = await p1;

            console.log(a);

            console.log(2);

        };

        console.log("fn end");

        fn();

 

4) 捕获错误信息:

  1. 直接使用catch
  2. Try...catch
  3. 优雅封装方法:
       let p1 = new Promise((resolve, reject) => {
            if (true) {
                resolve("success")
            } else {
                reject("失败")
            };
        });

        // promise自己调用catch方法
        // async function fn() {
        //     let a = await p1.catch(err => {
        //         console.log(err)
        //     });
        //     console.log(a);
        // };
        // fn();

        // try...catch
        // async function fn() {
        //     try {
        //         let a = await p1;
        //         console.log(a)
        //     } catch (error) {
        //         console.log(error)
        //     };
        // };
        // fn();

        // 优雅捕获错误
        function to(promise) {
            return promise.then(res => [null, res]).catch(err => [err,undefined]);
        };

        async function fn() {
            let [err, data] = await to(p1);
            console.log(err, data);
        };

        fn();

 

 

5) 解决回调地狱:

案例11秒打印一个1

 

     function fn2() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(1);
                }, 1000);
            })
        }
        async function fn3() {
            let a = await fn2();
            console.log(a);
            let b = await fn2();
            console.log(b);
            let c = await fn2();
            console.log(c);
            let d = await fn2();
            console.log(d);
        }
        fn3();

 

案例2ajax封装

 

   function myAjax({

            type = "get",

            url,

            data = {}

        }) {

            return new Promise(resolve => {

                $.ajax({

                    type,

                    url,

                    data,

                    dataType: "jsonp",

                    success: function(response) {

                        resolve(response);

                    }

                })

            });

        };

 

posted @ 2020-10-18 18:37  正经的流刺源  阅读(465)  评论(0编辑  收藏  举报