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封装吗?
我们在线,来聊聊吧
✕
您好,当前有专业客服人员在线,让我们来帮助您吧。
我们在线,来聊聊吧