JavaScript 事件循环(宏任务微任务)

2020-07-16  本文已影响0人  阿畅_

JavaScript 事件循环 宏任务微任务

JavaScript 的执行机制

什么是时间循环

  1. 让同步任务和异步任务分别进入不同的执行”场所“,同步的进入主线程,异步的进入 Event table 并注册函数。
  2. 当指定的事情完成时,Event table 会将整个函数移入 Event Queue (队列)
  3. 主线程内的任务执行完毕为空后,会去 Event Queue 读取对应的函数,进行主线程执行。
  4. 上面的过程不断的重复,也就是我们常说的 Event Loop 事件循环。

怎么知道主线程执行栈为空?

js 引擎存在 monitoring process 进程,会持续不断检查主线程执行栈是否为空,一旦是空,就会去 Event Queue 那里检查是否有等待被调用的函数。

ajax

let data = [];
$.ajax({
  url:www.javascript.com,
  data:data,
  success:() => {
    console.log('发送成功!');
  }
})
console.log('代码执行结束');

setTimeout

setTimeout(() => {
  console.log('123')
}, 1000)
console.log('console')

事件循环的顺序,决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。

setTimeout(function() {
  console.log('setTimeout');
})

new Promise(function(resolve) {
  console.log('promise');
}).then(function() {
  console.log('then');
})

console.log('console');
console.log('1');

setTimeout(function() {
  console.log('2');
  process.nextTick(function() {
    console.log('3');
  })
  new Promise(function(resolve) {
    console.log('4');
    resolve();
  }).then(function() {
    console.log('5')
  })
})
process.nextTick(function() {
  console.log('6');
})
new Promise(function(resolve) {
  console.log('7');
  resolve();
}).then(function() {
  console.log('8')
})

setTimeout(function() {
  console.log('9');
  process.nextTick(function() {
    console.log('10');
  })
  new Promise(function(resolve) {
    console.log('11');
    resolve();
  }).then(function() {
    console.log('12')
  })
})

  1. 代码作为第一个宏任务进入主线程,执行 console
  2. 遇到 setTimeout 把他的回调函数分发到宏任务 Event Queue 为 setTimeout1
  3. process.nextTick,函数分发到 Event Queue 中,记录 process1
  4. Promise 直接执行,输出7,then 被分发到微任务中,记录为 then1
  5. 又遇到 setTimeout,把他的回调函数分发到宏任务 Event Queue 为 setTimeout2

此时,已经有 宏任务 setTimeout1, setTimeout2, 微任务 process1 then1

  1. 发现有两个微任务,执行这两个微任务 process1 then1

此时,第一轮事件循环结束

  1. 第二轮从 setTimeout1 宏任务开始:输出 console,将 rocess.nextTick(),同样将其分发到微任务Event Queue中,记为process2。new Promise立即执行输出4,then也分发到微任务Event Queue中,记为then2。

此时有 宏任务 setTimeout2,和 微任务 process2 then2 未执行。

  1. 执行这两个微任务 process2 then2

此时 ,第二轮结束

  1. 第三轮开始,执行宏任务 setTimeout2 ,它有两个微任务 将process.nextTick()分发到微任务Event Queue中。记为process3。将then分发到微任务Event Queue中,记为then3。
  2. 执行这两个微任务,结束。

浏览器和Node事件循环的区别

上一篇 下一篇

猜你喜欢

热点阅读