EventLoop
答案:
了解几个概念:调用栈、同步/异步任务、宏任务/微任务
JavaScript本身是单线程,也就是同一时刻只能干一件事,JS任务包含了同步任务和异步任务,遇到执行函数会将其放入调用栈(先进后出)中,遇到setTimeout/setInterval等异步任务时,会把它放入到消息队列中,等主线程的任务执行完成以后,再回过头执行消息队列中的异步任务,如果异步任务中仍然有异步任务,会继续放入消息队列,以此类推,便形成了一个事件循环。
异步任务:
-
setTimeout
-
setInterval
异步任务又分为宏任务和微任务,promise就属于微任务。
详细解析:
Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制。
调用栈(Call Stack)
栈 是一种 LIFO(Last In, First Out)的数据结构,特点即 后进先出。
调用栈 本质上当然还是个栈,关键在于它里面装的东西,是一个个待执行的函数。
Event Loop 会一直检查 Call Stack 中是否有函数需要执行,如果有,就从栈顶依次执行。同时,如果执行的过程中发现其他函数,继续入栈然后执行。
先拿两个函数来说:
- 栈空
- 现在执行到一个 函数A,函数A 入栈
- 函数A 又调用了 函数B,函数B 入栈
- 函数B 执行完后 出栈
- 然后继续执行 函数A,执行完后A也 出栈
- 栈空
Javascript 有一个 main thread 主线程和 call-stack 调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。
- 开始,任务先进入 Call Stack
- 同步任务直接在栈中等待被执行,异步任务从 Call Stack 移入到 Event Table 注册
- 当对应的事件触发(或延迟到指定时间),Event Table 会将事件回调函数移入 Event Queue 等待
- 当 Call Stack 中没有任务,就从 Event Queue 中拿出一个任务放入 Call Stack
而 Event Loop 指的就是这一整个圈圈:
它不停检查 Call Stack 中是否有任务(也叫栈帧)需要执行,如果没有,就检查 Event Queue,从中弹出一个任务,放入 Call Stack 中,如此往复循环。