首页IT科技高级前端在公司做什么(高级前端进阶(五))

高级前端在公司做什么(高级前端进阶(五))

时间2025-05-02 23:50:27分类IT科技浏览3394
导读:详解JavaScript中的事件循环机制!!! 一、简单讲解...

详解JavaScript中的事件循环机制!!!

一           、简单讲解

这个大家应该或多或少都知道的

for (var i = 0; i < 10; i++) { setTimeout(() => { console.log(i); // 输出10个10 }); }

解析:先执行for循环            ,循环叠加i                 ,然后再执行setTimeout 10遍     ,所以会输出10个10

变体: for (let i = 0; i < 10; i++) { setTimeout(() => { console.log(i); // 依次输出0-9 }); }

我们知道var跟let本质区别就是作用域的问题            ,所以会联想到let导致的                  ,但在这一点上     ,并不是作用域问题      ,因为从事件循环机制来解释是有问题的

以上的代码等价于 for (var i = 0; i < 10; i++) { (function (i) { setTimeout(() => { console.log(i); }); })(i); // 立即执行函数                  ,以上的let应该是将代码特殊处理了下 }

立即执行函数:函数声明后立即执行            。

从事件循环的角度来说           ,应该先执行for循环将i叠加到10      ,执行完后再去执行for循环体(setTimeout),此时的i变成了10                  ,所以每次输出都是10           ,

这里使用let,应该是特殊处理了一下的                 。

二                 、深入讲解

我们知道JavaScript语言是单线程的                  ,至于为啥是单线程?

假设有两个线程                 ,一个在页面上新增一个div,另一个线程在页面上删除div            ,那最终听谁的?

那JavaScript怎么实现异步的呢?

在JavaScript中                 ,有两类任务:同步任务和异步任务     。

同步任务:普通的任务     ,依次从上往下执行            。

异步任务:又分为宏任务      、微任务                  。

宏任务:setTimeout跟setInterval

微任务:Promise().then() 这里要注意一下            ,Promise方法里面的是同步任务                  ,then里面的才是微任务

执行顺序:先执行同步任务     ,遇到异步任务      ,将其放入到宏任务或者微任务队列中                  ,然后优先执行微任务           ,接下来再去执行宏任务     。

简单的例子:

setTimeout(function() { console.log(1) }, 0); new Promise(function(resolve, reject) { console.log(2); // 这里是同步任务 resolve(); }).then((res) => { console.log(3); }) console.log(4); // 输出结果是 2 4 3 1

解析:从上往下执行      ,setTimeout是宏任务                  ,放到宏任务队列中           ,

Promise里面的是同步任务,所以先执行                  ,输出2                 ,then里面的是微任务,放到微任务队列中            ,

最后一个是同步任务                 ,执行     ,输出4            ,

然后执行微任务                  ,输出3

最后执行宏任务     ,输出1

来点难度的:

console.log(1); setTimeout(function () { console.log(2); }, 0); setTimeout(function () { console.log(3); setTimeout(function () { console.log(4); }, 0); }, 0); new Promise(function (resolve, reject) { console.log(5); resolve(); }).then((res) => { console.log(6); new Promise(function (resolve, reject) { console.log(7); resolve(); }).then((res) => { console.log(8); }); }); new Promise(function (resolve, reject) { console.log(9); resolve(); }) .then((res) => { console.log(10); }) .then((res) => { console.log(11); }); console.log(12); // 输出 1 5 9 12 // 6 7 10 8 11 // 2 3 4

解析:原理跟上面一样      ,不过需要注意的是                  ,8跟11的顺序:           ,在这里then的层级      ,将各个Promise里面第一层的then放在一起                  ,第二层的then放在一起           ,依此类推,

然后依次执行第一层的                  ,执行完第一层                 ,接下来执行完第二层,依此类推      。

第一层(6            ,7                 ,10)

第二层(8     ,11)

所以先输出8            , 再输出11的                  。

再来一个(也最可能出错或者无法理解的):

console.log(1); async function fn() { console.log(2); await console.log(3); console.log(4); // 这一步                  ,你应该会有问题 } setTimeout(() => { console.log(5); }, 0); fn(); new Promise((resolve) => { console.log(6); resolve(); }).then(() => { console.log(7); }); console.log(8); // 输出:1 2 3 6 8 4 7 5

解析:async await是Promise的语法糖     ,只是针对写法上的优化

将async await翻译成Promise: async function fn() { console.log(2); await console.log(3); console.log(4); // 这一步      ,你应该会有问题 } // 等价于 function fn() { return new Promise((resolve, reject) => { console.log(2); resolve( (() => { console.log(3); })() // 立即执行函数 ); }).then(() => { console.log(4); }); }

这样                  ,你应该能够明白           ,为啥输出3之后不是立即输出4了吧!

再来一道加深巩固的:

console.log(1); async function fn() { console.log(2); await console.log(3); await console.log(4); console.log(5); } setTimeout(() => { console.log(6); }, 2000); setTimeout(() => { console.log(7); }, 1000); fn(); new Promise((resolve) => { console.log(8); new Promise((resolve) => { console.log(9); resolve(); }).then(() => { console.log(10); }); resolve(); }).then(() => { console.log(11); new Promise((resolve) => { console.log(12); resolve(); }).then(() => { console.log(13); }); }); console.log(14); // 输出 1 2 3 8 9 14 // 4 10 11 12 5 13 // 7 6

我相信      ,你现在应该理解掌握了!

只要钻的深                  ,铁杵都能给你磨成针!!!

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
u盘加载速度缓慢是怎么回事?解决方法(U盘加载速度缓慢是怎么回事?解决方法) 网络优化技巧大揭秘——让你的网站排名大幅提升!(了解这些关键点,让你的网站优化不再迷茫)