javascript事件循环,宏任务与微任务

2022-09-23 09:48:45

一、内容解读知识储备

javascript中所有可以被执行的代码句,都可以是一个任务。

例如:console.log();for循环,alert();setTimeout()定时器;Promise.then()方法;这些都算是javascript中的“任务”。

但是,javascript中的任务又分为同步任务异步任务

异步任务的概念:所有不是javascript扫描到就立马执行的任务,被称为异步任务。比如setTimeOut(),Promise.then()方法,这些需要延迟执行的任务,是异步任务。

同步任务的概念:所有javascript扫描到不需要延迟执行,立马就可以执行的任务,被称为同步任务。比如:console.log();alert();switch()等等。

在同一代码段里,异步任务一定比同步任务晚执行。

同步任务和异步任务例子👇

//异步执行的setTimeOut(()=>{
	console.log('我是异步执行的');},100)//同步执行的
console.log('我不在异步任务中,是同步执行的');

以上这个例子的输出结果是👇
在这里插入图片描述

javascript明明是先扫描到setTimeOut()的,但是先输出的却是““我不在异步任务中,是同步执行的””这句话。
由此证明:异步任务晚于同步任务执行。

如果到这里依然没有明白什么是同步任务,什么是异步任务。请参考我的另一篇文章《javascript中的同步任务与异步任务》

二、宏任务和微任务

在javascript的所有异步任务之中又分为两种任务:宏任务和微任务。

其中宏任务有:setTimeOut(),setInterVal();requestAnimationFrame (浏览器独有);I/O线程;setImmediate (Node独有)等。

其中微任务有:promise.then()方法,Object.observe,MutationObserver,async/await等。

当浏览器扫描到上例的异步任务后,不会立马执行,浏览器会将这些任务放入js相对应的任务队列中。扫描到宏任务放入宏任务的任务队列,扫描到微任务放入微任务的任务队列。然后继续向下扫描并立马执行掉同步任务。

当所有的同步任务被执行完毕以后。浏览器才开始执行异步任务队列。
在异步任务队列中。浏览器会优先执行微任务队列里面的所有任务,当微任务队列中的所有任务被全部执行完毕后。才会去执行宏任务队列中的一个宏任务。

注意:执行完所有微任务后只会去宏任务队列中执行一个宏任务(不论宏任务队列中压了多少个宏任务,只执行一个),然后就会重新扫描微任务队列,查看是否有可执行的微任务。如果有,再次执行完所有的微任务,再回到宏任务队列中。
流程图如下👇
在这里插入图片描述

事件循环(event loop)

上面说了宏任务和微任务,是事件循环(event loop)讲解的储备。

浏览器扫描到同步任务后会直接将同步任务压入主线程的执行栈,在扫描到异步的任务的时候会加入宏任务/微任务队列。

在执行完所有同步任务后,浏览器会去微任务队列查询出所有的微任务,并压入执行栈,执行完所有微任务后浏览器会去宏任务队列中查询一个宏任务并压入执行栈。

执行完这个宏任务后浏览器又会去微任务队列中找出所有微任务执行…

如此一直循环。
这个过程,我们称为事件循环(event loop)

  • 作者:工边页字
  • 原文链接:https://blog.csdn.net/qq_48637854/article/details/124997282
    更新时间:2022-09-23 09:48:45