# 异步和事件循环
# JavaScript是单线程
JS引擎中负责解释和执行JavaScript代码的线程只有一个,但是实际上还存在其他的线程。例如:处理AJAX请求的线程、处理DOM事件的线程、定时器线程、读写文件的线程(例如在Node.js中)等等,可以理解为任务队列
# JavaScript同步与异步
# 同步
同步,也就是说按照顺序去做
console.log('node01')
console.log('node02')
// 输出:node01,node02
1
2
3
4
2
3
4
# 异步
异步,也就是说不完全按照顺序去做
console.log('node01')
setTimeout(function () {
console.log('node02');
},100)
console.log('node03')
// 输出:node01,node03,node02
1
2
3
4
5
6
7
2
3
4
5
6
7
异步实现理解:
- 1、主线程发起一个异步任务,工作线程接收任务
- 2、主线程可以继续执行后面的代码,同时工作线程执行异步任务
- 3、工作线程完成任务后,通知主线程
- 4、主线程收到通知后,执行相关操作,也就是我们所谓的回调函数
# 任务队列
一个 JavaScript 运行时包含了一个待处理的消息队列。每一个消息都关联着一个用以处理这个消息的函数。在事件循环期间的某个时刻,运行时从最先进入队列的消息开始处理队列中的消息。为此,这个消息会被移出队列,并作为输入参数调用与之关联的函数。正如前面所提到的,调用一个函数总是会为其创造一个新的栈帧(函数调用形成了一个栈帧)。函数的处理会一直进行到执行栈再次为空为止;然后事件循环将会处理队列中的下一个消息(如果还有的话)。
# 事件循环
主线程从"任务队列"中读取消息事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)
# 微任务(Microtasks)、宏任务(macrotasks)
- macrotasks: 整体代码script setTimeout setInterval setImmediate I/O UI渲染
- microtasks: Promise process.nextTick Object.observe MutationObserver
JS异步机制,遇到宏任务,先执行宏任务,宏任务执行结束,如果有可执行的微任务,执行微任务至结束,再开始新的宏任务,如果没有执行的微任务,直接开始新的宏任务。
参考:
← 多异步协作