searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

JavaScirpt中的Event Loop相关原理

2023-06-02 09:27:03
10
0

一、什么是Event Loop

  首先,需要了解的是,JavaScript是单线程语言,意味着它只有一个执行线程,等到上一个任务结束后才会执行下一个任务。如果上一个任务耗时过长,那下一个任务也要持续从而等待造成任务阻塞。为了解决这个问题,JavaScript有一个基于Event Loop(事件循环机制)的并发模型,负责执行代码、收集和处理事件以及执行队列中的子任务。

二、同步任务和异步任务

  JavaScript单线程任务被分为同步任务和任务异步任务。

  • 同步任务:指的是在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是处于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。
  • 异步任务:不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。


  在异步任务中,Event Table可以理解成一张事件和回调函数对应表,它就是用来存储 JavaScript 中的异步事件及其对应的回调函数的列表。Event Queue简单理解就是回调函队列,所以它也叫 Callback Queue。当 Event Table 中的事件被触发,事件对应的回调函数就会被推进这个 Event Queue,然后等待被执行。

三、宏任务和微任务

  Event Loop是通过任务队列的机制来进行协调的,任务队列里面是各种需要处理当前程序处理的异步任务。在JavaScript,异步任务一般包括宏任务和微任务。


  • 宏任务:主线程上的任务,它们会在主线程上执行。常见的宏任务包括 setTimeout, setInterval, setImmediate等。宏任务一般是与浏览器的渲染相关的任务。
  • 微任务:在主线程上执行的任务之前或之后立即执行的任务。常见的微任务包括then, process.nextTick, Object.observe, MutationObserver 等。微任务一般是与 JavaScript代码的执行相关的任务。

四、运行原理

  1. 运行同步任务, 微任务加入队列, 等待同步任务执行完毕
  2. 查看是否有微任务, 若有则执行, 按照先进先出的规则进行
  3. 微任务结束后执行宏任务, 执行完每一个宏任务之后都会再次进入第 2 步流程
  4. 微任务和宏任务都执行完毕

五、例子说明

console.log(1)

setTimeout(() => {
  console.log(2);
  Promise.resolve().then(() => {
    console.log(3)
  })
})

new Promise((resolve, reject) => {
  console.log(4)
  resolve(5)
}).then((data) => {
  console.log(data)
})

setTimeout(() => {
  console.log(6)
})

console.log(7)

// 输出结果:1,4,7,5,2,3,6
  • 输出过程:
  1. 执行同步任务console.log(1);// 输出结果:1
  2. 遇到setTimeout,放到宏任务队列中(回调函数记为callback1);
  3. 执行同步任务console.log(4);// 输出结果:1,4
  4. 遇到Promise.then,放到微任务队列中(回调函数记为callback2);
  5. 遇到setTimeout,放到宏任务队列中(回调函数记为callback3);
  6. 执行同步任务console.log(7);// 输出结果:1,4,7
  7. 所有同步任务执行完毕,开始执行异步任务,先依次执行微任务队列中的任务,再依次执行宏任务队列的队伍;
  8. 执行微任务callback2,console.log(data);// 输出结果:1,4,7,5
  9. 所有微任务执行完毕,开始依次执行宏任务队列中的任务;
  10. 执行宏任务callback1,console.log(2);// 输出结果:1,4,7,5,2
  11. 执行宏任务callback1后遇到Promise.then,放到微任务队列中(回调函数记为callback4);
  12. 第一个宏任务执行完毕,再次依次执行微任务队列中的任务;
  13. 执行微任务callback4,console.log(3);// 输出结果:1,4,7,5,2,3
  14. 所有微任务再次执行完毕,开始依次执行宏任务队列中的任务;
  15. 执行宏任务callback3,console.log(6);// 输出结果:1,4,7,5,2,3,6
  16. 所有任务执行完毕。
0条评论
作者已关闭评论
z****n
2文章数
0粉丝数
z****n
2 文章 | 0 粉丝
z****n
2文章数
0粉丝数
z****n
2 文章 | 0 粉丝
原创

JavaScirpt中的Event Loop相关原理

2023-06-02 09:27:03
10
0

一、什么是Event Loop

  首先,需要了解的是,JavaScript是单线程语言,意味着它只有一个执行线程,等到上一个任务结束后才会执行下一个任务。如果上一个任务耗时过长,那下一个任务也要持续从而等待造成任务阻塞。为了解决这个问题,JavaScript有一个基于Event Loop(事件循环机制)的并发模型,负责执行代码、收集和处理事件以及执行队列中的子任务。

二、同步任务和异步任务

  JavaScript单线程任务被分为同步任务和任务异步任务。

  • 同步任务:指的是在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是处于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。
  • 异步任务:不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。


  在异步任务中,Event Table可以理解成一张事件和回调函数对应表,它就是用来存储 JavaScript 中的异步事件及其对应的回调函数的列表。Event Queue简单理解就是回调函队列,所以它也叫 Callback Queue。当 Event Table 中的事件被触发,事件对应的回调函数就会被推进这个 Event Queue,然后等待被执行。

三、宏任务和微任务

  Event Loop是通过任务队列的机制来进行协调的,任务队列里面是各种需要处理当前程序处理的异步任务。在JavaScript,异步任务一般包括宏任务和微任务。


  • 宏任务:主线程上的任务,它们会在主线程上执行。常见的宏任务包括 setTimeout, setInterval, setImmediate等。宏任务一般是与浏览器的渲染相关的任务。
  • 微任务:在主线程上执行的任务之前或之后立即执行的任务。常见的微任务包括then, process.nextTick, Object.observe, MutationObserver 等。微任务一般是与 JavaScript代码的执行相关的任务。

四、运行原理

  1. 运行同步任务, 微任务加入队列, 等待同步任务执行完毕
  2. 查看是否有微任务, 若有则执行, 按照先进先出的规则进行
  3. 微任务结束后执行宏任务, 执行完每一个宏任务之后都会再次进入第 2 步流程
  4. 微任务和宏任务都执行完毕

五、例子说明

console.log(1)

setTimeout(() => {
  console.log(2);
  Promise.resolve().then(() => {
    console.log(3)
  })
})

new Promise((resolve, reject) => {
  console.log(4)
  resolve(5)
}).then((data) => {
  console.log(data)
})

setTimeout(() => {
  console.log(6)
})

console.log(7)

// 输出结果:1,4,7,5,2,3,6
  • 输出过程:
  1. 执行同步任务console.log(1);// 输出结果:1
  2. 遇到setTimeout,放到宏任务队列中(回调函数记为callback1);
  3. 执行同步任务console.log(4);// 输出结果:1,4
  4. 遇到Promise.then,放到微任务队列中(回调函数记为callback2);
  5. 遇到setTimeout,放到宏任务队列中(回调函数记为callback3);
  6. 执行同步任务console.log(7);// 输出结果:1,4,7
  7. 所有同步任务执行完毕,开始执行异步任务,先依次执行微任务队列中的任务,再依次执行宏任务队列的队伍;
  8. 执行微任务callback2,console.log(data);// 输出结果:1,4,7,5
  9. 所有微任务执行完毕,开始依次执行宏任务队列中的任务;
  10. 执行宏任务callback1,console.log(2);// 输出结果:1,4,7,5,2
  11. 执行宏任务callback1后遇到Promise.then,放到微任务队列中(回调函数记为callback4);
  12. 第一个宏任务执行完毕,再次依次执行微任务队列中的任务;
  13. 执行微任务callback4,console.log(3);// 输出结果:1,4,7,5,2,3
  14. 所有微任务再次执行完毕,开始依次执行宏任务队列中的任务;
  15. 执行宏任务callback3,console.log(6);// 输出结果:1,4,7,5,2,3,6
  16. 所有任务执行完毕。
文章来自个人专栏
JavaScirpt相关原理
1 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0