关于前端:js系列事件循环

一、简介

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…

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理