一、异步进阶-Event Loop
1. event loop
(事件循环/事件轮询)的机制
- JS 是单线程运行的
- 异步要基于回调来实现
- event loop 就是异步回调的实现原理
JS 如何执行?
- 从前到后,一行一行执行
- 如果某一行执行报错,则停止下面代码的执行
- 先把同步代码执行完,再执行异步
执行过程
- 先执行同步代码
- 把第一行代码推进调用栈,准备执行。
- 执行代码后,在控制台输出;再清空调用栈。
- 把第二行代码推进调用栈准备执行。
- 因为定时器是是Web中定义的,所以在WebAPIs中创建一个定时器。
- 清空调用栈。
- 最后一行代码推进调用栈中。
- 执行代码,清空调用栈。
- 一旦同步代码执行完,调用栈也空了。则浏览器内核开始启动
Event Loop
机制,这个机制的作用是,一步一步的去做循环, 每次循环都会到CallBack Queue中去寻找有没有函数要执行。- 5秒钟之后,定时器把
cb1
推到callback queue
Event Loop
把调用队列中的cb1函数拿到调用栈中,准备执行。- cb1函数执行到函数体中的代码。
- 函数体中代码执行完后进行清空。
- cb1函数执行完后调用栈也进行清空。
- 5秒钟之后,定时器把
- 先执行同步代码
总结event loop过程:
- 同步代码,一行一行放在
Call Stack
执行 - 遇到异步,会"记录"下,等待时机(定时、网络请求)
- 时机到了,就移动到
Callback Queue
- 如
Call Stack
为空(即同步代码执行完)Event Loop
开始工作 - 轮询查找
Callback Queue
,如有则移动到Call Stack
执行 - 然后继续轮询查找(像永动机一样)
- 同步代码,一行一行放在
DOM
事件和event loop
jsconsole.log('Hi'); setTimeout(function cb1() { console.log('cb1') // cb 即 callback }, 5000) console.log('Bye');
html<button id="btn1">提交</button> <script> console.log('Hi'); $('#btn1').click(function (e) { console.log('button clicked'); }) console.log('Bye') </script>
- JS是单线程的
- 异步(setTimeout、ajax等)使用回调,基于
event loop
DOM
事件也使用回调,基于event loop