前言
面试中被问到事件循环,我以为我是懂的,结果真被问到的时候,发现一个结果:脑子以为懂了,手其实根本没懂,只是简单的知道同步任务,异步任务,宏任务,微任务,并没有深刻理解其执行原理,所以决定自己写一篇笔记,加深理解。
关于js的任务
js是按照语句顺序执行的
同步任务:需要执行的任务在主线程上排队,一次执行
异步任务:没有立马执行但是需要被执行的任务,放在任务队列里面
js的事件循环
所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
主线程之外,还存在一个”任务队列”(task queue)。只要异步任务有了运行结果,就在”任务队列”之中放置一个事件。
js引擎存在monitoring process进程,会持续不断的检查主线程“执行栈”是否为空,一旦”执行栈”中的所有同步任务执行完毕,系统就会读取”任务队列”,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
主线程不断重复上面的第三步,即为Event Loop(时间循环)。
如图所示:
异步任务
宏任务:整体script代码 > setInterval/setTimeout
微任务:process.nexttrick(nodejs的内容) > Promise
其执行流程为:
进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。
上代码:
1 | console.log(1); |
下面是分析过程:
console.log(1);
:同步任务,推入主线程执行栈setTimeout
:异步任务,属于宏任务,推入宏任务的Event Queue上new Promise
:new函数为同步任务,推入主线程执行栈,then为异步任务,属于微任务,推入微任务的Event Queue上console.log(6);
:同步任务,推入主线程执行栈执行主线程执行栈:1 -> 3 -> 6
判断有没有微任务,执行微任务: 4 -> 5
执行下一个宏任务:2
练习
接下来找了一个复杂的例子,虽然复杂,但是只要懂了上面的js事件循环原理,也可以很轻易的推导出结果:
1 | console.log(1); |
这个结果是什么呢?试着分析一下(不写答案了,以备将来我忘记了,仍能当做练习题来看)