当前位置: 首页 > Web前端 > JavaScript

面试官:说说EventLoop,microtasks,macrotasks

时间:2023-03-27 13:14:00 JavaScript

前言JS是单线程语言,也就是说所有任务都需要排队,只有上一个任务完成后才会执行下一个任务。由此带来的问题是:如果JS的执行时间过长,会导致页面渲染不连贯,导致页面渲染和加载有阻塞感。为了解决这个问题,JS中出现了同步和异步。它们之间的本质区别在于每个进程在管道上的执行顺序不同。在讲JS任务执行机制之前,我们首先要了解什么是同步任务和异步任务。同步任务:即主线程上的任务从上到下依次执行。当前任务完成后才能执行下一个任务。异步任务:不进入主线程,而是进入任务队列的任务。执行后会产生回调函数,通知主线程。当主线程上的任务执行时,会调用最早通知自己的回调函数,从而进入主线程执行。一、事件循环的概念介绍事件循环事件循环也称为事件队列。两者是一个概念。事件循环不属于js代码本身的范畴,而是属于js编译器的范畴。讨论js中的事件循环是没有意义的。也就是说,js代码可以理解为一个人在一个公司做什么,而事件循环就相当于一个公司的规章制度。两者不是一个级别的概念。2、microtasks和macrotasks的概念介绍Microtasks和macrotasks都属于js代码的范畴。js代码主要分为两类:同步代码和异步代码。异步代码又分为:microtask和macrotask3.事件循环EventLoop执行机制1.当你进入script标签时,就进入了第一个事件循环。2.遇到同步代码,立即执行3.遇到宏任务,放入宏任务队列。4.遇到微任务,将其放入微任务队列。5.执行所有同步代码。6.执行微任务代码。7.microtask代码执行完毕后,清空队列,寻找下一个macrotask。重复步骤1,直到所有宏任务都被清除,这种重复执行的机制称为事件循环。画图描述事件循环4.容易出错的点(1)。Promise本身是一个同步代码(只是一个容器),只有then()方法才是微任务(2)。await右边的表达式仍然会立即执行,表达式后面的代码就是microtask。await微任务可以转换为等效的promise微任务分析(3)。脚本标签本身就是一个宏任务。当页面上有多个script标签时,浏览器会将script标签解析为一个宏任务。看到这里,你应该对eventloop有了一些了解,下面我给大家看几道面试题。1.1.先在主线程执行log(1)2.当有两个await时,只有第一个await右边的代码会立即执行log(4),后面的几行代码会放到microtask队列中间.3.在主线程上执行log(6)4.执行从第4行到第6行的微任务2.1。先在主线程上执行1、5、7。2、主线程的同步任务执行完后,会先执行microtasks。执行Promise的then方法中的代码,打印63。microtask执行完后,finally执行timer中的macrotask,打印2,3,43。详见前端高级面试题1的答案。在主线程上先执行同步代码,打印12。执行第9行函数,输入async1,async1其实声明了一个promise,而promise是同步代码,会顺序执行并打印async2函数中的4,只有.then代码会被添加到microtask队列中,相当于执行了async2(),然后将下面的代码添加到一个microtask队列中。3.回到主线程,遇到setTimeout(),加入宏任务队列4.主线程继续执行。前面说过,promise是同步代码,.then之后的回调会加入到微任务队列中,所以在第13行会打印75,主线程执行完后,开始执行微任务队列中的任务,如下先进先出的原则,在第四行打印2。然后执行第5行第二个await右边的代码,打印5。此时第6行加入到microtask队列中。6.然后会执行第二个microtask,也就是16行代码,打印8个。那么第17行此时也会加入microtask队列。然后依次执行第6行和第17行的两个microtask,打印3和97。microtask执行完后,开始执行宏任务setTimeout,并在第11行打印6。总结所有同步任务都在主线程上执行,形成一个调用栈。遇到异步任务,进入异步处理模块,注册回调函数;当指定的事件完成时(比如ajax请求响应返回,setTimeout延迟到指定时间),异步处理模块会将这个回调函数移入异步任务队列。当栈中的代码执行完毕,执行栈中的任务为空时,主线程会先检查微任务队列中是否有任务,如果有,则依次执行微任务队列中的所有任务,直到微任务队列为空;然后查看宏任务队列中是否有任务,如果有则取出第一个宏任务加入执行栈,然后清空执行栈,查看微任务,循环直到所有任务执行完毕。以上就是我对JS执行原理的整理和理解,希望能给读者带来一些帮助。如有误解或表述不当请指正。最后问大家一个问题,大家可以在评论区留下答案