zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Node.js:async和await完整学习笔记

2023-09-27 14:22:47 时间
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
        nodejs文档
        https://nodejs.dev/en/

        通过async可以快速的创建异步函数
    */
    function fn() {
      return Promise.resolve(10)
    }

    /* 
        通过async可以快速的创建异步函数
            异步函数的返回值会自动封装到一个Promise中返回

        在async声明的异步函数中可以使用await关键字来调用异步函数
    */

    async function fn2() {
      return 10;
    }

    fn().then(r => {
      console.log(r);
    })

    let result = fn2()

    console.log(result);

    function sum(a,b) {
      return new Promise(resolve => {
        setTimeout(() => {
          resolve(a+b)
        },2000)
      })
    }

    /* 
      Promise解决了异步回调函数的问题
        虽然通过链式调用解决了回调地狱,但是链式调用太多以后还是不好看
        我们可能都希望可以用同步的方式去调用异步的代码
    */

    async function fn3() {
      sum(123,456).then(r => {
        console.log(r);
      })
    }

    async function fn4() {
      // sum(123,456)
      //   .then(r => sum(r,7))
      //   .then(r => sum(r,8))
      //   .then(r => console.log(r))
      /* 
          当我们通过await方式去调用异步函数时,它会暂停代码的运行
          直到异步代码执行的有结果的时候,才会将结果返回
          注意 await只能用于 async声明的异步函数中 或 es模块的顶级作用域中

          在异步函数中使用是为了 防止await会阻止其他程序的执行
          放在异步函数中使用,在调用该异步函数的时候不会阻止其他程序的正常运行

          如果在该异步函数中,await后面还有其他程序函数则会被阻塞执行

          总结:await只会阻塞异步函数内部的代码,不会影响外部的代码

          通过await调用异步代码时,需要通过try-catch来处理异常
      */
      // let result = await sum(123,456)
      // result = await sum(result,7)
      // result = await sum(result,8)

      // console.log(result);
      try {
        let result = await sum(123,456)
        result = await sum(result,7)
        esult = await sum(result,8)

        console.log(result);
      }catch(e) {
        console.log("出错了");
      }
    }
    fn3()
    fn4()
    console.log("测试的全局输出~~");

    /* 
      如果async声明的函数中没有写await,那么它里面的代码就会依次执行
          但是有一点它会返回的时Promise
    */
    async function fn5() {
      console.log(1);
      console.log(2);
      console.log(3);
      return 10
    }
    fn5()
    console.log(4);
    /* 
      上面的代码等价于下面的这段代码
    */
    function fn6() {
      return new Promise(resolve => {
        console.log(1);
        console.log(2);
        console.log(3);
        // 如果函数没有返回值,可以直接写resolve()
        resolve(10)
      })
    }
    console.log(4);
    fn6()

    async function fn7() {
      console.log(1);
      /* 
          当我们使用await调用函数后,当前函数后边的所有代码
            会在当前函数执行完毕后,被放入到微任务队列中
      */
      await console.log(2);
      /* 
          await后边的所有代码,都会放到微任务队列中执行
      */
      console.log(3);
    }
    fn7()
    console.log(4);

    function fn8() {
      return new Promise(resolve => {
        console.log(1);
        /* 
          要让fn7和fn8是一样的效果
            因为在console.log(2);前加了await
              所以之后的代码在这里就没有意义了
                必须放在then中执行
        */
        console.log(2);
        // console.log(3);
        resolve()
      }).then(r => {
        console.log(3);
      })
    }
    fn8()
    console.log(4);

    async function fn9() {
      console.log(1);
      /* 
          当我们使用await调用函数后,当前函数后边的所有代码
            会在当前函数执行完毕后,被放入到微任务队列中
      */
      await console.log(2);
      /* 
          await后边的所有代码,都会放到微任务队列中执行
      */
      await console.log(3);
      console.log(5);
    }
    fn9()
    console.log(4);

    function fn10() {
      return new Promise(resolve => {
        console.log(1);
        /* 
          要让fn9和fn10是一样的效果
            因为在console.log(2);前加了await
              所以之后的代码在这里就没有意义了
                必须放在then中执行
        */
        console.log(2);
        // console.log(3);
        resolve()
      }).then(r => {
        console.log(3);
      }).then(r => {
        console.log(5);
      })
    }
    fn10()
    console.log(4);

    async function fun11() {
      await console.log("零小唬");
    }
    fun11()

    /* 
      不在模块化js中调用时可以使用以下方法进行
    */
    ;(async () => {
      await console.log("零小唬");
      /* 
        此时执行的时候会报错,原因没有分号
      */
    })()
  </script>
</body>
</html>

js的模块化调用方式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script type="module">
    await console.log(123);
  </script>
</body>
</html>
await console.log(1239);
//注意:上面这段代码在js文件中会报错,但是在mjs中可以正常执行