# 异步和事件循环

# JavaScript是单线程

JS引擎中负责解释和执行JavaScript代码的线程只有一个,但是实际上还存在其他的线程。例如:处理AJAX请求的线程、处理DOM事件的线程、定时器线程、读写文件的线程(例如在Node.js中)等等,可以理解为任务队列

# JavaScript同步与异步

# 同步

同步,也就是说按照顺序去做

console.log('node01')
console.log('node02')

// 输出:node01,node02
1
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

异步实现理解:

  • 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异步机制,遇到宏任务,先执行宏任务,宏任务执行结束,如果有可执行的微任务,执行微任务至结束,再开始新的宏任务,如果没有执行的微任务,直接开始新的宏任务。

参考:

更新于: 7/8/2020, 7:46:15 AM