小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
event loop(事件循环/事件轮询)
- JS 是单线程运行的
- 异步要基于回调来实现
- event loop 就是异步回调的实现原理
JS 如何执行?
- 从前到后,一行一行执行
- 如果某一行执行报错,则停止下面代码的执行
- 先把同步代码执行完,再执行异步代码
示例
console.log('Hi')
setTimeout(function cb1() {
console.log('cb1') // cb 即 callback
}, 5000)
console.log('Bye')
evetn loop 过程
Call Stack:调用栈Callback Queue:回调函数队列
开始执行 console.log('Hi'),推入调用栈(Call Stack)里,调用栈会执行这条代码语句,执行完后打印 Hi
之后,清空调用栈;
执行 setTimeout 函数,是一个 Web APIs,第一个参数是一个 cb1 函数,把他放到定时器里面,定时器的定时是5000ms,5000ms后把 cb1 函数放到 Callback Queue 里面
执行完后,清空调用栈;
执行最后一行代码,推入调用栈(Call Stack)里,调用栈会执行这条代码语句,执行完后打印 Bye
执行完后,清空调用栈;
一旦所有同步代码执行完,Call Stack 空了,浏览器内核立刻启动 Event Loop 机制,此时 Event Loop 在循环中,一直到 Web APIs 里的5000ms过后,定时器把 cb1 推到 Callback Queue;Event Loop 发现有待执行的队列,会把待执行的拿到 Call Stack 里面
Call Stack 触发函数执行
执行完后,清空调用栈;
所有代码执行完毕!!
总结:
- 同步代码,一行一行放在
Call Stack执行 - 遇到异步,会先“记录”下,等待时机(定时、网络请求等)
- 时机到了,就移动到
Callback Queue - 如
Call Stack为空(即同步代码执行完),Event Loop开始工作 - 轮询查找
Callback Queue,如有则移动到Call Stack执行 - 然后继续轮询查找(像永动机一样)