100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > js的事件循环机制 同步和异步 以及宏任务与微任务的执行顺序

js的事件循环机制 同步和异步 以及宏任务与微任务的执行顺序

时间:2023-12-29 16:14:27

相关推荐

js的事件循环机制 同步和异步 以及宏任务与微任务的执行顺序

前置知识点(重要):

1.什么是事件循环:js是单线程语言,同个时间执行一件事(同步),但是他可以有一个异步队列,遇到异步操作(比如说ajax这种阻塞时间很久的事情)把它们先放入异步队列,并且继续往下执行,当同步队列执行完了,他就会去异步队列里面找刚才存放起来的事件,然后按顺序执行他们。

2.异步队列(异步任务)又包含宏任务和微任务,微任务先与宏任务执行

宏任务有:

微任务有:

3.同为微任务的Promise与process.nextTick(callback),先执行后者(process.nextTick(callback)当下一轮事件开始循环的时候第一时间执行他的callback)

下图为他们之间的关系图:

通过一个例子来解释执行整个事件循环,与同步异步,宏任务微任务执行顺序

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.log,输出1。

遇到setTimeout,其回调函数被分发到宏任务Event Queue中。我们暂且记为setTimeout1。

– 遇到process.nextTick(),其回调函数被分发到微任务Event Queue中。我们记为process1。

– 遇到Promise,new Promise(是同步,then才是异步)直接执行,输出7。then(Promise中then是异步)被分发到微任务Event Queue中。我们记为then1。

– 又遇到了setTimeout,其回调函数被分发到宏任务Event Queue中,我们记为setTimeout2。

上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了1和7。

我们发现了process1和then1两个微任务。

执行process1,输出6。

执行then1,输出8。

好了,第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。

2.第二轮时间循环从setTimeout1宏任务开始:

首先输出2。接下来遇到了process.nextTick(),同样将其分发到微任务Event Queue中,记为process2。

new Promise立即执行输出4,then也分发到微任务Event Queue中,记为then2

如表所示:这一轮取出setTimeout1,分析发现两个微任务,则先执行这两个微任务。

3.第三轮宏任务setTimeout2开始执行

如表所示:这一轮取出setTimeout2,分析发现两个微任务,则先执行这两个微任务process3和then3。

输出10。

输出12。

第三轮事件循环结束,第三轮输出9,11,10,12。

整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。(请注意,node环境下的事件监听依赖libuv与前端环境不完全相同,输出顺序可能会有误差)

图解js执行机制–事件循环

首先,整体的script(作为第一个宏任务)开始执行的时候,会把所有代码分为同步任务、异步任务两部分

同步任务会直接进入主线程依次执行

异步任务会再分为宏任务和微任务

宏任务进入到Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中

微任务也会进入到另一个Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中

当主线程内的任务执行完毕,主线程为空时,会检查微任务的Event Queue,如果有任务,就全部执行,如果没有就执行下一个宏任务

上述过程会不断重复,这就是Event Loop,比较完整的事件循环

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。