• async/await


    async await

    我们直接进入主题!!!

    1.async和await是什么?
    
            async:
                是ES7语法,用于声明一个function是异步函数。
            await:
                等待一个异步方法完成。
        ps:await只能出现在async函数中,不然会报错,如示例1-1;
            Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules
            Await只在异步函数和顶级模块体中有效.
    

      

      

     1 /*示例 1-1*/
     2     let fun = function (){
     3         console.log('错误示例');
     4     }
     5     await fun();
     6 
     7     let fun1 = function(){
     8         console.log('正确示例');
     9     }
    10     let fun =async function (){
    11         await fun1();
    12     }
    13     fun();

      

    2.async到底干了什么?
           (一):
            我们先看一下async声明的函数,返回值到底是个什么。
        ps:如示例2-1;
            可以看到返回的其实就是一个promise对象。Promise {<fulfilled>: "async"}
            所以,async直接返回一个promise对象。如果在函数中直接return一个直接量,async会通过promise.resolve()封装成promise对象。
        ps:Promise.resolve(e)可以看作是 new Promise(resolve => resplve(e))的简写,可以快速将字面量对象或其他对象分装成promise实例。
            (二):
            使用async不用await可以处理返回值吗?
        ps:如示例2-2-1;
            如示例2-2-2,async声明的函数是一个promise对象,所以我们当然可以用then()链去处理。
            (三):
            到这里就会产生一个疑问,既然async返回是一个promise对象,并且promise的特点就是无等待,在没有await的情况下会立即执行,不会阻塞后面的语句,和普通的promise并无二致,
            我们为什么要用async和await呢?
    
            我们看示例2-3-1,模拟了一个异步操作,因为promise并不会造成阻塞,所以打印2输出为null,打印1会在一秒以后输出111,
            想一个问题如果我们有的代码是基于异步完成之后的结果,要怎么处理?对,我们可以在then()函数中写,如果有多个promise并且相互依赖呢?
    

      

     1     /*示例2-1*/
     2 
     3     let fun = async function(){
     4         return 'async';
     5     }
     6     console.log(fun());//Promise {<fulfilled>: "async"}
     7 
     8     /*示例2-2-1*/
     9     fun().then(e=>{
    10         console.log(e);//async
    11     })
    12 
    13     /*示例2-3-1*/
    14     var param = null;
    15 
    16     let fun =  () => {
    17         return new Promise(resolve => {
    18             setTimeout(() => resolve(function(){
    19                 param = '111';
    20             }), 1000);
    21         });
    22     }
    23 
    24     fun().then(v => {
    25         v();
    26         console.log(param,'1');
    27     });
    28     console.log(param,'2');
    3.await到底在等什么?
            (一):
            官方介绍,await等待的是一个promise对象或者是其它值。
            实际await等待的是一个返回值,所以await后边可以接普通函数,或者是直接量。
        ps:如示例3-1-1。
            (二):
            await等到了要等的东西,然后呢?
            await是一个运算符,用于组成表达式,await表达式的运算结果取决于等到的东西。
            如果await等到的不是一个promise对象,那await运算结果就是等到的东西。
            如果await等到的是一个promise对象,那会阻塞后面的代码,等着promise对象resolve,然后得到resolve的值,最为await运算结果。
            注意:
                阻塞,只是async把所有的阻塞都封装在一个promise对象中异步执行,这也是await必须使用在async函数中的原因。
        ps:如示例3-2-1。
            示例会先执行打印3 输出null,然后一秒以后异步结束执行1,2。
    

      

     1     /*示例3-1-1*/
     2     let fun = function () {
     3         return "fun";
     4     }
     5 
     6     let asyncFun = async function () {
     7         return Promise.resolve("asyncFun");
     8     }
     9 
    10     async function test() {
    11         const v1 = await fun();
    12         const v2 = await asyncFun();
    13         console.log(v1, v2);
    14     }
    15 
    16     test();
    17     /*示例3-2-1*/
    18     var param = null;
    19 
    20     let fun = () => {
    21         return new Promise(resolve => {
    22             setTimeout(() => resolve(function () {
    23                 param = '111';
    24             }), 1000);
    25         });
    26     }
    27 
    28     let awaitFun = async function () {
    29         await fun().then(v => {
    30             v();
    31             console.log(param, '1');
    32         });
    33         console.log(param, '2');
    34     }
    35     awaitFun();
    36     console.log(param, '3');
    4.目前看来使用Promise和async,await好像并没有什么区别?
            (一):
            我们简单做一个比较。
            不用async/await:
        ps:示例4-1-1。
            使用async/await:
        ps:示例4-1-2。
            好,我们发现好像并没有什么区别?so,优势到底在哪里?
            (二):
            async/await优势:
            其实单一的promise并不能发现async/await优势,但是如果处理多个优势就出来了。
            说白了async/await好像就是用来优化promise。
            现在,我们假设一个业务,分成多步,且每一步都依赖于上一步的结果。
        ps:示例4-2-1。
            有没有发现什么???
            在看一个,把业务要求改一下,仍然是三个步骤,但每一个步骤都需要之前每个步骤的结果。
        ps:示例4-2-2。
            哇,是不是很神奇!!!
    
      1     /*示例4-1-1*/
      2     let fun = function () {
      3         return new Promise(resolve => {
      4             setTimeout(() => resolve("not async/await!!!"), 1000);
      5         });
      6     }
      7 
      8     fun().then(v => {
      9         console.log("async", v);
     10     });
     11     /*示例4-1-2*/
     12     let fun = function () {
     13         return new Promise(resolve => {
     14             setTimeout(() => resolve("is async/await!!!"), 1000);
     15         });
     16     }
     17 
     18     async function test() {
     19         const v = await fun();
     20         console.log(v);
     21     }
     22 
     23     test();
     24 
     25     /*示例4-2-1*/
     26     /**
     27      * 传入参数 n,表示这个函数执行的时间(毫秒)
     28      * 执行的结果是 n + 200,这个值将用于下一步骤
     29      */
     30     function getTime(n) {
     31         return new Promise(resolve => {
     32             setTimeout(() => resolve(n + 200), n);
     33         });
     34     }
     35 
     36     function step1(n) {
     37         console.log(`step1 with ${n}`);
     38         return getTime(n);
     39     }
     40 
     41     function step2(n) {
     42         console.log(`step2 with ${n}`);
     43         return getTime(n);
     44     }
     45 
     46     function step3(n) {
     47         console.log(`step3 with ${n}`);
     48         return getTime(n);
     49     }
     50     /*promise实现*/
     51     function doIt() {
     52         console.time("doIt");
     53         const time1 = 300;
     54         step1(time1)
     55             .then(time2 => step2(time2))
     56             .then(time3 => step3(time3))
     57             .then(result => {
     58                 console.log(`result is ${result}`);
     59                 console.timeEnd("doIt");
     60             });
     61     }
     62 
     63     doIt();
     64     /*async/await实现*/
     65     async function doIt() {
     66         console.time("doIt");
     67         const time1 = 300;
     68         const time2 = await step1(time1);
     69         const time3 = await step2(time2);
     70         const result = await step3(time3);
     71         console.log(`result is ${result}`);
     72         console.timeEnd("doIt");
     73     }
     74 
     75     doIt();
     76 
     77     /*4-2-2*/
     78     function step1(n) {
     79         console.log(`step1 with ${n}`);
     80         return getTime(n);
     81     }
     82 
     83     function step2(m, n) {
     84         console.log(`step2 with ${m} and ${n}`);
     85         return getTime(m + n);
     86     }
     87 
     88     function step3(k, m, n) {
     89         console.log(`step3 with ${k}, ${m} and ${n}`);
     90         return getTime(k + m + n);
     91     }
     92     /*async/await实现*/
     93     async function doIt() {
     94         console.time("doIt");
     95         const time1 = 300;
     96         const time2 = await step1(time1);
     97         const time3 = await step2(time1, time2);
     98         const result = await step3(time1, time2, time3);
     99         console.log(`result is ${result}`);
    100         console.timeEnd("doIt");
    101     }
    102 
    103     doIt();
    104 
    105     /*promise实现*/
    106     function doIt() {
    107         console.time("doIt");
    108         const time1 = 300;
    109         step1(time1)
    110             .then(time2 => {
    111                 return step2(time1, time2)
    112                     .then(time3 => [time1, time2, time3]);
    113             })
    114             .then(times => {
    115                 const [time1, time2, time3] = times;
    116                 return step3(time1, time2, time3);
    117             })
    118             .then(result => {
    119                 console.log(`result is ${result}`);
    120                 console.timeEnd("doIt");
    121             });
    122     }
    123 
    124     doIt();
    5.总结
            个人理解async/await是用来解决同步异步,更重要的是优化了promise。

    ok,到此结束,后续会把实际应用场景更新进来,欢迎指出毛病哦!

     

    6.补充:
                处理错误逻辑
        ps:示例6-1-1。
                (一): try/catch/finally
                    如果try块中的任何代码发生了错误,就会立即退出代码执行过程,然后接着执行catch块,此时,catch块会接收到一个包含错误信息的对象。
                    finally子句一经使用,其代码无论如何都会执行。
                    只要代码中包含finally子句,则无论try或catch语句块中包含什么样的代码——甚至return语句,都不会阻止finally子句的执行。
                    执行顺序try->catch->finally。
                (二):JavaScript throw 语句:
                    Throw抛出一个错误。
                    创建自定义错误。
                    可抛出字符串,数字,逻辑值或对象。
                    !!!!!抛出错误javascript会停止往下执行。
                    ps: throw “ too bing”
                    throw 500
                    throw new Error(‘’这是一个错误!!!);
                (三):函数定义方式
                    (1):函数声明
                        function fun (a,b){
                            return a*b;
                        }
                        fun(1,2);
                        不会立即执行。
                    (2):函数表达式
                        let a = function(a,b){
                            return a*b;
                        }
                        a(1,2);
                        等同于匿名函数通过变量名调用。
                    (3):Function()构造函数
                        let fun = new Function('a','b','return a*b');
                        fun(1,2);
                    (4):函数提升
                        提升(Hoisting)是 JavaScript 默认将当前作用域提升到前面去的的行为。
                        提升(Hoisting)应用在变量的声明与函数的声明。
                    ps:示例6-3-4
                    (5):函数执行顺序
                    ps:示例6-3-5
                    (6):作用域
                    ps:示例6-3-6
    

      

     

     1 let fun = async function (type) {
     2         if (type) {
     3             return '示例6-1-1';
     4         } else {
     5             throw new Error('sorry is Error!!!')
     6         }
     7     }
     8     async function test() {
     9         try {
    10             let a = await fun(false);
    11             console.log(a)
    12         } catch (err) {
    13             console.log(err);
    14             return;
    15         } finally {
    16             console.log('我执行了!!!')
    17         }
    18     }
    19     test();
     1 /*示例6-3-4*/
     2     function fun(a, b) {
     3         return a * b;
     4     }
     5     console.log(fun(1, 2), '函数声明');
     6 
     7     let a = function (a, b) {
     8         return a * b;
     9     }
    10     console.log(a(1, 2), '函数表达式'); //不能在初始化之前使用
    11     let fun1 = new Function('a', 'b', 'return a*b');
    12     console.log(fun1(1, 2), '构造函数');
    13 
    14     /*示例6-3-5*/
    15     function f() { return 1; }
    16     console.log(f()); // 第四个函数把第一个函数覆盖 4
    17 
    18     var f = new Function("return 2;");
    19     console.log(f()); // 第二个函数把第四个函数覆盖 2
    20 
    21     var f = function () { return 3; }
    22     console.log(f()); // 第三个函数把第二个函数覆盖 3
    23 
    24     function f() { return 4; }
    25     console.log(f()); // 第四个函数已经被覆盖 3
    26 
    27     var f = new Function("return 5;");
    28     console.log(f()); // 第五个函数把第三个函数覆盖 5
    29 
    30     var f = function () { return 6; }
    31     console.log(f()); // 第六个函数把第五个函数覆盖 6
    32 
    33     /*示例6-3-6*/
    34     var k = 4;
    35     window.onload = function () {
    36 
    37         var k = 1;
    38 
    39         function t1() {
    40             var k = 2;
    41 
    42             function test() {
    43                 return k;
    44             }
    45             console.info(test()); // 弹出 2
    46 
    47             var test = function () {
    48                 return k;
    49             };
    50             console.info(test()); // 弹出 2
    51 
    52             var test = new Function("return k;"); // 每次执行的时候,动态的new,顶级作用域,无法获得局部变量
    53             console.info(test()); // 弹出 4
    54 
    55         }
    56         t1();
    57     };
  • 相关阅读:
    总结在ssm整合中,Mybatis出现Mapped Statements collection already contains value for xxxxx的解决方案
    一般二叉树的创建,前序,中序,后序遍历
    无向图的广度优先遍历和深度优先遍历(简易实现)
    为什么局部内部类中访问同一方法中的变量,该变量一定要是final修饰的
    uml统一建模语言学习笔记(一)
    Font Awesome 字体使用方法, 兼容ie7+
    Java的三种代理模式&完整源码分析
    xxl-job源码分析
    MySQl看这一篇就够了
    第二部分:Spring中配置mongodb
  • 原文地址:https://www.cnblogs.com/yushihao/p/14961214.html
Copyright © 2020-2023  润新知