首页>>前端>>JavaScript->JS事件循环(Event Loop)机制及面试题分析

JS事件循环(Event Loop)机制及面试题分析

时间:2023-12-02 本站 点击:0

1. 事件循环Event Loop 概念介绍

事件循环Event Loop又叫事件队列,两者是一个概念.

官方定义: 事件循环指的是js代码所在运行环境(浏览器、nodejs)编译器的一种解析执行规则。

在js中讨论事件循环是没有意义的, : 事件循环不属于js代码本身的范畴,而是属于js编译器的范畴

通俗的来说, js代码可以理解为是一个人在公司中具体做的事情, 而 事件循环 相当于是公司的一种规章制度。 两者不是一个层面的概念。

2. 事件循环Event Loop 执行机制

说到事件循环,就必须先了解JS代码的分类和执行机制

2.1 JS代码的分类

同步任务:同步任务不需要进行等待,必须立即看到执行结果,比如console,alert

异步任务:异步任务需要等待一定的时候才能看到结果,比如setTimeout、网络请求

下面是常用的宏任务和微任务代码:

注意:

new Promise函数体里面的代码是同步代码,只有promise.then()的then括号里面的代码是微任务代码

new Promise((resolve, reject) => {console.log(8); //同步代码resolve();console.log(9) //同步代码}).then(res => {console.log(10);//微任务代码})

async/await 右边的代码是同步代码, async/await下面的才是微任务代码

async function fnOne() {            console.log(2); //同步任务            await fnTwo(); // 同步任务            console.log(3); //异步微任务        }        async function fnTwo() {            console.log(4);        }        fnOne();

2.2 JS事件循环执行机制

1.进入到script标签,就进入到了第一次事件循环.

2.遇到同步代码,立即执行

3.遇到宏任务,放入到宏任务队列里.

4.遇到微任务,放入到微任务队列里.

5.执行完所有同步代码

6.执行微任务代码

7.微任务代码执行完毕,本次队列清空

寻找下一个宏任务,重复步骤1

以此反复直到清空所以宏任务,这种不断重复的执行机制,就叫做事件循环

了解了js代码的分类和js事件循环的机制之后,  不管多复杂的面试题都能轻轻松松的拿下了.

3. 面试题

3.1 先来个简单的

 <script>        console.log(1) //同步代码        setTimeout(function () {            console.log(2)            new Promise(function (resolve) {                console.log(3)                resolve()            }).then(function () {                console.log(4)            })        })        new Promise(function (resolve) {            console.log(5)            resolve()        }).then(function () {            console.log(6)        })        setTimeout(function () {            console.log(7)            new Promise(function (resolve) {                console.log(8)                resolve()            }).then(function () {                console.log(9)            })        })        console.log(10)    </script>

思路分析: 1, 先按照代码类别执行同步代码

2, 同步代码执行完毕之后,再去执行微任务里面的代码,此时已执行完的代码顺序是这样的:

3, 微任务的代码执行完毕之后,先执行宏任务里面的第一块代码

4, 再去执行宏任务里面的第二块代码

最后,代码的执行顺序如下:

3.2 再来个难一点的

<script>        console.log(1);        async function fnOne() {            console.log(2);            await fnTwo(); // 右边先执行右侧的代码, 然后等待            console.log(3);        }        async function fnTwo() {            console.log(4);//        }        fnOne();        setTimeout(() => {            console.log(5);        }, 2000);        let p = new Promise((resolve, reject) => { // new Promise()里的函数体会马上执行所有代码            console.log(6);            resolve();            console.log(7);        })        setTimeout(() => {            console.log(8)        }, 0)        p.then(() => {            console.log(9);        })        console.log(10);    </script>    <script>        console.log(11);        setTimeout(() => {            console.log(12);            let p = new Promise((resolve) => {                resolve(13);            })            p.then(res => {                console.log(res);            })            console.log(15);        }, 0)        console.log(14);    </script>

思路分析: 1, 先判断每个代码是同步还是异步,先执行同步代码

2, 同步代码执行完毕之后再去微任务里面执行微任务代码

3, 微任务代码执行完毕后,再去执行宏任务里面的代码

注意点: (1)如果页面有多个script标签,多余的script标签可以理解为是一个独立的事件循环, 并且script标签是一个特殊的宏任务,优先级比定时器更高执行

所以此处宏任务队列里面优先执行script标签里面的代码,然后再执行定时器里面的代码

另外微任务的script标签里面既有同步代码,又有异步代码,又需要进行第二轮的代码分类

接下来,再去执行宏任务里面三个定时器里面的代码

以此类推,最后代码的执行顺序就是这样子滴

总之一句话,只要搞懂了事件循环机制和js代码分类,再复杂的面试题都能so easy的解答出来!

原文:https://juejin.cn/post/7101674091962171400


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/JavaScript/9517.html