• mfist
    2019-09-19
    1. 首先在主协程中初始化异步函数foo和bar,碰到console.log打印script start;
    2. 解析到setTimeout,初始化一个Timer,创建一个新的task
    3. 执行bar函数,将控制权交给协程,输出bar start,碰到await,执行foo,输出foo,创建一个 Promise返回给主协程
    4. 将返回的promise添加到微任务队列,向下执行 new Promise,输出 promise executor,返回resolve 添加到微任务队列
    5. 输出script end
    6. 当前task结束之前检查微任务队列,执行第一个微任务,将控制器交给协程输出bar end
    7. 执行第二个微任务 输出 promise then
    8. 当前任务执行完毕进入下一个任务,输出setTimeout
    展开
     10
     27
  • Luke
    2019-09-19
    generator 函数是如何暂停执行程序的?
    答案是通过协程来控制程序执行。
    generator 函数是一个生成器,执行它会返回一个迭代器,这个迭代器同时也是一个协程。一个线程中可以有多个协程,但是同时只能有一个协程在执行。线程的执行是在内核态,是由操作系统来控制;协程的执行是在用户态,是完全由程序来进行控制,通过调用生成器的next()方法可以让该协程执行,通过yield关键字可以让该协程暂停,交出主线程控制权,通过return 关键字可以让该协程结束。协程切换是在用户态执行,而线程切换时需要从用户态切换到内核态,在内核态进行调度,协程相对于线程来说更加轻量、高效。
    async function实现原理?
    async function 是通过 promise + generator 来实现的。generator 是通过协程来控制程序调度的。
    ​在协程中执行异步任务时,先用promise封装该异步任务,如果异步任务完成,会将其结果放入微任务队列中,然后通过yield 让出主线程执行权,继续执行主线程js,主线程js执行完毕后,会去扫描微任务队列,如果有任务则取出任务进行执行,这时通过调用迭代器的next(result)方法,并传入任务执行结果result,将主线程执行权转交给该协程继续执行,并且将result赋值给yield 表达式左边的变量,从而以同步的方式实现了异步编程。
    所以说到底async function 还是通过协程+微任务+浏览器事件循环机制来实现的。
    展开
    
     8
  • 许童童
    2019-09-19
    感谢老师的分享,懂了,生成器+Promise+自动迭代器=async/await。
    
     3
  • 淡
    2019-09-30
    你好,这还有个小疑问:
    就是foo函数被标记上async后,会隐式生成一个promise,然后在await foo()处,await本身又会生成一个promise_,这两个promise是什么关系?
     2
     2
  • bobi
    2019-09-21
    //foo 函数
    function* foo() {
        let response1 = yield fetch('https://www.geekbang.org')
        console.log('response1')
        console.log(response1) // 这里为什么是undefined
        let response2 = yield fetch('https://www.geekbang.org/test')
        console.log('response2')
        console.log(response2) // 这里为什么是undefined
    }
    老师,在你举的生成器和Promise结合的例子中,为什么执行器里面取不到接口的值啊?
    展开
     1
     1
  • tomision
    2020-02-10
    async function inner() {
      console.log('inner')
    }

    async function foo() {
      console.log('foo start')
      await inner()
      console.log('foo end')
    }

    async function bar() {
      console.log('bar start')
      await foo()
      console.log('bar end')
    }

    老师 如果 bar 函数的实现是这样的呢?协程可以再开协程么?
    展开
    
    
  • 4!!
    2020-02-01
    父协程就是主线程吗?
    
    
  • NikkiZeng
    2020-02-01
    老师,请问一下,在promise的执行器中,如果resolve/reject函数被调用的时候,promise状态就会发生改变,随之,对应的then方法身上的回调也会选择其中一个被触发了,为什么是resolve还会被放到微任务中呢?
    
    
  • Objectivezt
    2020-01-01
    search 下 : “将主线程控制权交给foo协程,并将vaule值传给协程, ” value有书写错误。
    
    
  • Zzzrd
    2019-12-23
    const test2 = async () => {
            let a = await 100;
            console.log(a);
       }
       const pro = test2();
        console.log(pro);
        pro.then(res => {
            console.log(res);
        })

    老师,这里的res为什么是undefined,不是100?
    展开
     1
    
  • Zzzrd
    2019-12-23
    script start;
        bar start;
        promise executor
        script end
        bar end
        promise then
        setTimeout
    展开
    
    
  • Inspect
    2019-11-24
    yield 'generator 2' 这段代码写错了,全部都是yield 'generator 2' 应该是1-4
    
    
  • 歌顿
    2019-10-21
    await 100 讲清楚了,但是 await async 函数没有讲清楚啊。
    比如说 foo函数被标记上async后,会隐式生成一个promise,然后在await foo()处,await本身又会生成一个promise_,这两个promise是什么关系?
     1
    
  • 忘忧草的约定
    2019-09-26
    老师对于'bar end'和'promise then'的顺序我还是有点疑问,既然是microtask中恢复bar协程的的执行、不应该是先执行“bar end”吗
    
    
  • 忘忧草的约定
    2019-09-26

    'script start'
    'bar start'
    'foo'
    'promise executor'
    'script end'
    'bar end'
    'promise then'
    'setTimeout'
    展开
    
    
  • 蓝配鸡
    2019-09-25
    Script then
    Bar start
    Foo
    Promise executor
    Script end
    Promise then
    Settimeout

    老师相信我真的不是跑出来的😂

    主要考查了promise,微任务, 宏任务, 还有使用async await时候协程时间的相互合作。
    展开
    
    
  • 小兵
    2019-09-24
    async function foo() {
        console.log(1)
        let a = await 100
        // 从这里开始的内容是不是可以看作then绑定的回调函数的内容啊,看图又不像,不好理解。
        console.log(a)
        console.log(2)
    }
    console.log(0)
    foo()
    console.log(3)
    展开
    
    
  • Louis Hu
    2019-09-20
    老师您好:
    想请问一下如果 await 是一个Promise的对象呢?
    这时会发生什么?
     1
    
  • 柒月
    2019-09-20
    async function foo() {
        console.log('foo'); //3 foo
    }
    async function bar() {
        console.log('bar start');
        await foo()
        console.log('bar end'); //6 bar end
    }
    console.log('script start');//1 script start
    setTimeout(()=>{
        console.log('setTimeout'); 7//setTimeout
    },0)
    bar();//2 bar start
    new Promise(function (resolve) {
        resolve();
    }).then(function () {
        console.log('promise then'); //5 promise then
    })
    console.log('script end');// 4 script end

    浏览器和node环境是有点不一样呢?为啥呢?
    展开
    
    
  • Geek_f74777
    2019-09-19
    老师,课后习题中的第一个异步foo函数中会异步执行返回一个Promise对象,那么这个Promise对象在创建返回的过程中,是否会往微任务队列中添加微任务?既然foo()执行返回的结果已经是一个Promise了,那么V8引擎还会将await后的foo()
    返回的Promise再进行一次Promise封装吗?
    
    
我们在线,来聊聊吧