一、简介

javaScript是单线程非阻塞的脚本语言。

单线程

单线程是指在执行JavaScript代码的时候,主线程依照程序执行。

非阻塞

非阻塞是指执行异步工作的时候,主线程会挂起工作,期待异步工作返回后果后按程序执行

事件循环

同步工作:立刻执行的工作,同步工作个别会间接进入到主线程中执行

异步工作:异步执行的工作,异步工作又分为微工作(micorotask)和宏工作(macrotack)

同步工作进入主线程,即主执行栈,异步工作进入工作队列,主线程内的工作执行结束为空,会去工作队列读取对应的工作,推入主线程执行。上述过程的一直反复就是事件循环

二、宏工作与微工作

异步工作又分为微工作(micorotask)和宏工作(macrotack)

微工作

在以后宏工作执行完结之后立刻执行的工作,执行完微工作在执行下一个宏工作。

常见的微工作:
Promise.then
Object.observe
MutationObserver
process.nextTick(ndoe环境)

宏工作

每次执行栈执行的工作就是宏工作(包含从工作队列中获取下一个宏工作队列去执行)。

常见的宏工作:
script代码
setTimeout
setInterval
I/O
UI交互事件
postMessage

三、代码剖析

实例代码

console.log('script start')async function async1() {  console.log('async1 start')  await async2()  console.log('async1 end')  return 'async then'}async function async2() {  console.log('async2 end')}async1()setTimeout(function() {  console.log('setTimeout')}, 0)async1().then(function (message) { console.log(message) })new Promise(resolve => {  console.log('Promise')  resolve()})  .then(function() {    console.log('promise1')  })  .then(function() {    console.log('promise2')  })console.log('script end')

流程步骤

1、遇到console间接打印 'script start'
2、执行async1,打印console('async1 start'),遇到await阻塞async2前面的流程。
3、执行async2,打印 'async2 end',async2前面的代码留着前面执行(工作队列:async1)
4、遇到定时器,属于新的宏工作,留着前面执行(工作队列:async1、定时器)
5、执行async1,打印出'async1 start''async2 end'
6、.then 属于微工作,放入微工作队列,前面再执行(工作队列:async1、then、定时器)
7、遇到 new Promise,这个是间接执行的,打印 'Promise'
8、.then 属于微工作,放入微工作队列,前面再执行(工作队列:async1、then(async1)、then(promise)、定时器)
9、遇到console间接打印 'script end'

执行工作队列宏工作(async1、then、then、定时器)
1、执行async2前面的代码,打印 'async1 end'
2、执行async1 async2前面的代码,打印 'async1 end',then放入微工作队列
3、执行promise 第一个then事件,打印 'promise1'第二个then放入微工作队列
4、执行微工作队列async1 then事件,打印 'async then'
5、执行promise第二个then事件,打印 'promise2'
6、最初执行定时器 'setTimeout'

输入后果:

'script start''async1 start''async2 end''async1 start''async2 end''Promise''script end''async1 end''async1 end''promise1''async then''promise2''setTimeout'

四、参考文献

https://github.com/febobo/web...