精华内容
下载资源
问答
  • 2021.06.09 async await原理

    2021-06-09 16:30:15
  • 我们经常用asyncawait实现异步方法,那么他的实现原理是什么呢,今天介绍一下。 一.代码 1:介绍原理之前,先看一段简单的代码: 2:代码执行结果,如下所示,想必结果和大家的预期是一样的: 二.工具 研究async...

    我们经常用async和await实现异步方法,那么他的实现原理是什么呢,今天介绍一下。

    一.代码

    1:介绍原理之前,先看一段简单的代码:
    在这里插入图片描述
    2:代码执行结果,如下所示,想必结果和大家的预期是一样的:
    在这里插入图片描述

    二.工具

    研究async await使用的工具是dotPeek,注意:要勾选 show compiler-generated code。下载地址:https://www.jetbrains.com/decompiler/download/#section=web-installer
    在这里插入图片描述

    三.原理

    也许大家都听说过,async await 是一个语法糖,编译器会生成一个状态机,那么这个状态机是什么样子,它又是怎样工作的呢?

    1:通过dotPeek工具,进行反编译,会看到如下两段代码:
    在这里插入图片描述
    在这里插入图片描述
    2:方法SetName:

    1. 在方法SetName上添加了一个状态机特性,类型是Program.d__1
    2. 在方法SetName在方法里面先实例化了一个状态机
    3. 传递参数
    4. 使用AsyncVoidMethodBuilder创建了一个builder
    5. 将状态机的状态置成-1
    6. 启动状态机

    3:类d__1,我们只关注里面的核心代码IAsyncStateMachine.MoveNext(),这里包括状态机的执行逻辑:

    在这里插入图片描述

    4:介绍一下AsyncVoidMethodBuilder,否则整个过程串不起来:

    1. 通过使用AsyncVoidMethodBuilder的start方法启动状态机,那么如何启动的呢?让我们看下源码。
      在这里插入图片描述
      由此可见 ,通过Start方法,我们可以看到内部是通过调动状态机的MoveNext的方法,启动状态机的。

    2. 通过使用AsyncVoidMethodBuilder的AwaitUnsafeOnCompleted方法注册了任务完成后的回调方法,那么是如何实现的呢?让我们看下源码。
      在这里插入图片描述
      由此可见,通过调用GetCompletionAction来获取状态机的执行方法(MoveNext),并赋值给continuation,将continuation注册到awaiter的回调函数。

    5.看一下await的执行流程图,如下所示:
    在这里插入图片描述

    四.总结

    当我们使用async方法是,编译器就会生成一个状态机,在方法内部的await会做如下两件事:
    1:执行await表达式
    2:查看等待的方法是否完成

    1. 如果完成,则执行方法中剩余的部分
    2. 如果没有完成,当任务完成后,用回调函数来执行剩余的部分
    展开全文
  • async await 原理吸收

    2019-05-14 14:56:00
    https://www.jianshu.com/p/862ab6d1a2f6 转载于:https://www.cnblogs.com/liaolongfei/p/10862178.html

    https://www.jianshu.com/p/862ab6d1a2f6

    转载于:https://www.cnblogs.com/liaolongfei/p/10862178.html

    展开全文
  • 一旦遇到 await 就会先返回,等到触发的异步操作完成, 再接着执行函数体内后面的语句 深入理解 理解async函数需要先理解Generator函数, 因为async函数是Generator函数的语法糖 function* foo(x) { 可以使用yield...
    async 函数返回一个 Promise 对象,
    let a = await fn() 
    console.log(2) 这个要等待a这个微任务才执行
    如果后面跟的是函数,函数里先执行,但是等待的结果是异步的微任务
    let a = await 1; 
    如果后面跟的是普通值,等待的结果也是异步的微任务
    console.log(2) a这个结果是微任务,所以会阻塞后面的代码,
    所以2打印也是微任务
    

    深入理解

    理解async函数需要先理解Generator函数,
    因为async函数是Generator函数的语法糖,
    通过yield关键字可以暂停generator函数返回的遍历器对象的状态
    

    Generator函数运行逻辑如下:

    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    };
    
    var hw = helloWorldGenerator();
    hw.next()
    // { value: 'hello', done: false }
    
    hw.next()
    // { value: 'world', done: false }
    
    hw.next()
    // { value: 'ending', done: true }
    
    hw.next()
    // { value: undefined, done: true }
    
    遇到yield表达式,就暂停执行后面的操作,
    并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。
    
    下一次调用next方法时,也是将紧跟在yield后面的那个表达式的值,
    作为返回的对象的value属性值
    
    如果没有再遇到新的yield表达式,就一直运行到函数结束,
    直到return语句为止,并将return语句后面的表达式的值,
    作为返回的对象的value属性值。
    如果该函数没有return语句,则返回的对象的value属性值为undefined
    

    异步解决方案

    回调函数
    Promise 对象
    generator 函数
    async/await
    

    总结一下

    async await 内部通过Generator函数和promise 去封装的
    因为async返回的是个promise
    Generator是异步解决的一种方案,最大特点则是将异步操作同步化表达出来
    

    generator

    yield表达式可以暂停函数执行,next方法用于恢复函数执行
    ,这使得Generator函数非常适合将异步任务同步化

    const gen = function* () {
      const f1 = yield readFile('/etc/fstab');
      const f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    
    const asyncReadFile = async function () {
      const f1 = await readFile('/etc/fstab');
      const f2 = await readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    
    

    还能利用Generator函数,在对象上实现Iterator接口

    function* iterEntries(obj) {
      let keys = Object.keys(obj);
      for (let i=0; i < keys.length; i++) {
        let key = keys[i];
        yield [key, obj[key]];
      }
    }
    
    let myObj = { foo: 3, bar: 7 };
    
    for (let [key, value] of iterEntries(myObj)) {
      console.log(key, value);
    }
    
    展开全文
  • async 函数中可能会有 await 表达式,这会使 async 函数暂停执行,等待 Promise 的结果出来,然后恢复async函数的执行并返回解析值(resolved)。 注意, await 关键字仅仅在 async function中有效。如果在 ...
  • 1.Async Await 原理(注:await 只能出现在 async 函数中) 当调用一个 async 函数时,会返回一个 Promise 对象 (关键) async 函数中可能会有 await 表达式,await表达式 会使 async 函数暂停执行,直到表达式中的...
  • async await原理

    万次阅读 多人点赞 2018-07-08 21:58:30
    在公司的项目中,我们经常用到async await 这样的函数,它的作用也很奇特,可以让异步的函数等待异步执行的结果出来再继续往下进行。我一直很好奇这是怎么做到的,它内部的机理是怎么样的,就一个关键词在函数前面加...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,884
精华内容 5,553
关键字:

asyncawait原理