事件循环:微任务 宏任务

前提:

JavaScript引擎有一个监听事件(monitoring process)的功能,会持续不断的检查js引擎的主线程执行栈是否为空,如果为空就会去取事件触发线程存放在事件队列中的回调函数执行。

micro task 和 macro task

  • 浏览器的事件循环依靠已事件队列,但是一个进程中不止一个事件队列,大致可以分为micro task和macro task,常见的微任务和宏任务分别包括:

micro task :

  • nextTick
  • callback
  • Promise
  • process.nextTick
  • Object.observe
  • MutationObserver

macro task:
-setTimeout

  • setInterval
  • I/O
  • script代码块

event loop

  • 事件队列在同步队列执行完后,首先会执行nextTick,等nextTick执行完成后,
  • 然后会先执行micro task, 等micro task队列空了之后,才会去执行macro task,
  • 如果中间添加了micro task加入了micro task队列,会继续去执行micro task队列,然后再回到macro task队列。

注意:

一段代码块就是一个宏任务。所有一般执行代码块的时候,也就是程序执行进入主线程了,主线程会根据不同的代码再分微任务和宏任务等待主线程执行完成后,不停地循环执行。
主线程(宏任务) => 微任务 => 宏任务 => 主线程

范例:

setTimeout( () =>
    console.log('timeout')
)

new Promise(function(resolve) {
   
    for(var i = 0; i < 10; i++) {
         resolve();
    }
    console.log('a');
}).then(function() {
    console.log('promise');
})

console.log('c');
"a"
"c"
"promise"
"timeout"

1.当前task运行,执行代码。首先setTimeout的callback被添加到tasks queue中;
2.实例化promise,输出 a;
3.promise.then的callback被添加到microtasks queue中;
4.输出"c" ;
5.已到当前task的end,执行microtasks,输出"promise" ;
6.执行下一个task,输出"timeout"。

总结:

1.主线程(宏任务) => 微任务 => 宏任务 => 主线程
2.微任务会被添加到一轮事件循环的尾部执行,就是吊车尾啦比如promise;
3.宏任务则被添加下一轮事件循环,主线程同步任务以被清空后执行。

你可能感兴趣的:(事件循环:微任务 宏任务)