• 异步函数(async/await)


    异步函数

    异步函数,也称为"async/await" (语法关键字),是ES6 期约模式在ECMAScript 函数中的应用。async/await 是ES8 规范新增的。为了解决利用异步结构组织代码的问题。

    async

    async 关键字用于声明异步函数。这个关键字可以用在函数声明、函数表达式、箭头函数和方法上:

        async function foo() {}   
        let bar = async function() {};  
        let baz = async() => {};   
        class Qux {   
            async qux() {}   
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    异步函数如果使用return 返回了值(没有return 则会返回undefined),这个值会被Promise.resolve() 包装成一个期约对象。

        async function foo(){
            console.log(1)
        }
    
        console.log(foo()); //promise {:undefined}
        foo().then(console.log) //undefined
        console.log(2)
        //1
        //2
        //undefined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    await

    await 关键字可以暂停异步函数代码的执行,等待期约解决。await 会暂停执行异步函数后面的代码,让出JS 运行时的执行线程。这个行为与生成器函数中的yield 关键字是一样的。await 关键字同样是尝试 “解包” 对象的值,然后将这个值传给表达式,再异步恢复异步函数的执行。

    await 关键字必须在异步函数中使用;异步函数的特质不会扩展到嵌套函数。否则会抛出SyntaxError;

    async function foo(){
        await Promise.resolve(3);
    }
    foo();
    
    • 1
    • 2
    • 3
    • 4

    async/await 中真正起作用的是await。异步函数如果不包含await 关键字,其执行基本上跟普通函数没什么区别。

    JavaScript 运行时在碰到await 关键字时,会记录在哪里暂停执行。等到await 右边的值可用了,js运行时会向消息队列中推送一个任务,这个任务会恢复异步函数的执行。

    因此,即使await 后面跟着一个立即可用的值,函数的其他部分也会被异步求值。

        async function foo() { 
            console.log(2);   
            await null;
            console.log(4);  
        }   
        console.log(1);
        foo();
        console.log(3);
        // 1
        // 2
        // 3
        // 4
        
        控制台中输出结果的顺序很好地解释了运行时的工作过程:
        (1)打印1(2)调用异步函数foo()(3)(在foo()中)打印2(4)(在foo()中)await关键字暂停执行,为立即可用的值null向消息队列中添加一个任务;
        (5)foo()退出;
        (6)打印3;
        (7)同步线程的代码执行完毕;
        (8)JavaScript运行时从消息队列中取出任务,恢复异步函数执行;
        (9)(在foo()中)恢复执行,await取得null值(这里并没有使用);
        (10)(在foo()中)打印4(11)foo()返回。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    异步函数策略

    实现sleep()

    很多人在刚开始学习JavaScript时,想找到一个类似Java中Thread.sleep()之类的函数,好在程序中加入非阻塞的暂停。以前,这个需求基本上都通过setTimeout()利用JavaScript运行时的行为来实现的。

    有了异步函数之后,就不一样了。一个简单的箭头函数就可以实现sleep():

     async function sleep(delay) {
            return new Promise((resolve) => setTimeout(resolve, delay));
        }
    
        async function sleepfoo(){
            const t0 = Date.now();
            await sleep(2000);
            const t1 = Date.now();
            console.log(t1 - t0);
        }
        sleepfoo()
        //2002  任务队列执行,时间不一定
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    利用平行执行

    串行执行期约

    栈追踪与内存管理

    小结

    异步函数是将期约应用于JavaScript函数的结果。异步函数可以暂停执行,而不阻塞主线程。无论是编写基于期约的代码,还是组织串行或平行执行的异步代码,使用异步函数都非常得心应手。异步函数可以说是现代JavaScript工具箱中最重要的工具之一。

  • 相关阅读:
    Debian install MySQL if use root remove command ‘sudo‘
    人工智能轨道交通行业周刊-第60期(2023.9.11-9.17)
    Linux网卡状态查看
    Spark基础【RDD单Value类型转换算子】
    openssl生成key和pem文件
    练习接口测试详细步骤
    YOLOv5涨点必备!改进损失函数EIoU,SIoU,AlphaIoU,FocalEIoU,Wise-IoU
    快速看懂(找到)VUE框架的管理系统代码
    快消品企业数字化转型解决方案
    Qt中的线程同步:确保多线程程序的安全性
  • 原文地址:https://blog.csdn.net/qq_36865892/article/details/127553262