• Node.js之async 和 await 关键字及微任务和宏任务


    async 和 await 关键字

    async 和 await 是 ES2017 中提出来的,async 和 await 两个关键字的出现,简化的 Promise 的使用。

    async 关键字

    async关键字使用比较简单,所以 async 的使用注意以下三点即可 :

    1.async 用于修饰一个 function
    2.async 修饰的函数,总是返回一个 Promise 对象
    3.函数内的所有值,将自动包装在 resolved 的 promise 中

    // async 用于修饰一个 function
    // 1. async 修饰的函数,总是返回一个 Promise 对象
    // 2. 函数的返回值,将自动包装在 resolve 的 promise 中
    
    // 1. async 修饰的函数,总是返回一个 Promise 对象
    async function fn() {// 2. 函数的返回值,将自动包装在 resolve 的 promise 中return '哈哈哈';
    }
    
    // 以后看一下博客文章之类的东西,里面会有一些变量使用 :foo 和 bar , 无意义;
    const foo = fn();
    console.log(foo);
    foo.then(res => {console.log(res);
    });
    
    // 注意: async修饰的函数被称为异步函数,可他不是异步执行;
    console.log('我是最后一行代码'); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    await关键字

    await关键字比较繁琐,注意点比较多。首先,await 只能出现在 async 函数内,await 让 JS 引擎等待直到promise完成并返回结果,语法:

    let value = await promise对象; // 等待promise对象的结果,然后将结果赋值给 value

    由于await需要等待promise执行完毕,所以 await会 暂停函数的执行,但不会影响其他同步任务。

    所以,await总结如下四点:

    1.await只能出现在异步函数中!
    2.await能停止代码执行,让后面的同步代码,先执行;
    3.await后面跟随的是一个promise对象;
    4.await返回的是: Promise对象中的then()中的回调函数中的参数res;

    // 定义一个方法,为的就是返回一个 Promise 对象,让下面的await使用;
    async function getPromise() {return '哈哈哈';
    }
    console.log(1);
    // 1.await只能出现在async修饰的函数中!
    async function fn() {console.log(2);// 2.await后面跟随的是一个promise对象;// 3.await返回的是: Promise对象中的then()中的回调函数中的参数res;const str = await getPromise();console.log(str);// 4.await能停止代码执行,让后面的同步代码,先执行;console.log(3);
    }
    
    // 调用
    fn();
    console.log(4);
    
    // // 以前用法: 
    // axios().then(res => {
    // res.data.map()
    // });
    // // 以后用法: 
    // async function name() {
    // let res = await axios();
    // res.data.map();
    // } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    async 和 await 解决回调地狱

    // async 和 await 解决回调地狱也要用到 then-fs ,因为他直接返回 Promise 对象;
    ​
    // 导入 then-fs
    import thenFs from 'then-fs';
    ​
    // await 一定要出现在异步函数中
    async function fn() {
        let str1 = await thenFs.readFile('./txt/a.txt', 'utf8');
        console.log(str1);
        let str2 = await thenFs.readFile('./txt/b.txt', 'utf8');
        console.log(str2);
        let str3 = await thenFs.readFile('./txt/c.txt', 'utf8');
        console.log(str3);
    }
    ​
    // 调用函数
    fn(); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    JS执行机制(事件循环)

    1.js代码开始执行后,主线程执行栈中会把任务分为两类.
    2.一类是同步任务, 一类是异步任务; 主线程执行栈优先执行同步任务,
    3.异步任务会被放入特定的处理程序中,满足条件后,被放到消息(任务/事件)队列中,
    4.主线程执行栈中所有的同步任务执行完毕之后,通过事件循环去消息(任务/事件)队列中,
    5.挑选优先满足条件的程序,放入主线程执行栈中执行。事件循环,周而复始,一直执行。

    微任务和宏任务

    在ES3 以及以前的版本中,JavaScript本身没有发起异步请求的能力,也就没有微任务的存在。在ES5之后,JavaScript引入了Promise,这样,不需要浏览器,JavaScript引擎自身也能够发起异步任务了。 ​ Tick会触发浏览器渲染,Promise不会触发,所以更加轻量级,多使用;

    宏任务

    (macro)task,可以理解是每次执行栈执行的代码就是一个宏任务

    • 主线程上的执行栈中所有的代码块
    • setTimeout
    • setInterval
    • Ajax
    • 事件

    微任务

    微任务(microtask)是宏任务中的一个部分,它的执行时机是在同步代码执行之后,下一个宏任务执行之前。总结起来,微任务有:

    • Promise.then
    • process.nextTick(Node.js 环境)

    宏任务和微任务执行机制

    JS优先执行同步任务,然后执行微任务,最后执行宏任务。

    总结:Promise中的then()比大部分异步代码,优先执行!

    // 结论: 如果同一时间既有宏任务又有微任务触发,那么优先执行微任务;
    // 宏任务是宿主发起的会触发重构,比较浪费资源,后执行;
    // 微任务是js解释器发起的不会触发重构,比较节省资源,先执行;
    // 宏任务
    setTimeout(() => {//执行后 回调一个宏事件console.log('1')
    }, 0)
    // 同步代码
    console.log('2');
    // 同步代码
    new Promise((resolve) => {console.log('3');resolve()
    // 微任务
    }).then(() => {console.log('4');
    // 微任务
    }).then(()=>{console.log('5')
    })
    // 同步代码
    console.log('6')
    // 23 6 4 5 1 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    最后是原图

  • 相关阅读:
    JS:如何创建新元素并添加到页面中
    代码随想录训练营第32天|LeetCode 122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II
    Spring Boot 框架学习笔记(七)整合Quartz调度框架
    【C++/2023年10月1日】
    css overflow-x: scroll 滚动不展示/隐藏滚动条 /如何滚动
    剑指 Offer 10- II. 青蛙跳台阶问题
    Go 接口:深入内部原理
    nginx动态新增模块
    【K8S系列】Service基础入门
    win 10 mstsc连接 RemoteApp
  • 原文地址:https://blog.csdn.net/web2022050902/article/details/126242130