JS进阶 异步

297 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

event loop(事件循环/事件轮询)

  • JS 是单线程运行的
  • 异步要基于回调来实现
  • event loop 就是异步回调的实现原理

JS 如何执行?

  • 从前到后,一行一行执行
  • 如果某一行执行报错,则停止下面代码的执行
  • 先把同步代码执行完,再执行异步代码

示例

console.log('Hi')

setTimeout(function cb1() {
    console.log('cb1') // cb 即 callback
}, 5000)

console.log('Bye')

image.png

evetn loop 过程

  • Call Stack:调用栈
  • Callback Queue:回调函数队列

开始执行 console.log('Hi'),推入调用栈(Call Stack)里,调用栈会执行这条代码语句,执行完后打印 Hi

image.png

之后,清空调用栈;

image.png

执行 setTimeout 函数,是一个 Web APIs,第一个参数是一个 cb1 函数,把他放到定时器里面,定时器的定时是5000ms,5000ms后把 cb1 函数放到 Callback Queue 里面

image.png

执行完后,清空调用栈;

image.png

执行最后一行代码,推入调用栈(Call Stack)里,调用栈会执行这条代码语句,执行完后打印 Bye

image.png

执行完后,清空调用栈;

image.png

一旦所有同步代码执行完,Call Stack 空了,浏览器内核立刻启动 Event Loop 机制,此时 Event Loop 在循环中,一直到 Web APIs 里的5000ms过后,定时器把 cb1 推到 Callback QueueEvent Loop 发现有待执行的队列,会把待执行的拿到 Call Stack 里面

image.png

image.png

Call Stack 触发函数执行

image.png

执行完后,清空调用栈;

image.png

所有代码执行完毕!!

总结:

  • 同步代码,一行一行放在 Call Stack 执行
  • 遇到异步,会先“记录”下,等待时机(定时、网络请求等)
  • 时机到了,就移动到 Callback Queue
  • Call Stack 为空(即同步代码执行完),Event Loop 开始工作
  • 轮询查找 Callback Queue,如有则移动到 Call Stack 执行
  • 然后继续轮询查找(像永动机一样)