一文搞懂:JavaScript 事件循环机制 (event loop)

这个你可能得去问 javascript 的作者了。

执行栈

由于 javascript 是单线程语言,因此只有一个执行栈(调用栈)

function baz() {

console.log(“exec”)

}

function bar() {

baz();

}

function foo() {

bar();

}

foo();

我们可以用一个动画来演示执行栈的调用过程

根据动画流程,我们详细说一下调用栈的情况

  1. main 函数,也就是把整个 javascript 看成一个函数,入栈

  2. foo 函数被执行,入栈

  3. bar 函数被执行,入栈

  4. baz 函数被执行,入栈

  5. console.log 函数被执行,入栈

  6. console.log 函数执行完毕,出栈

  7. baz 函数执行完毕,出栈

  8. bar 函数执行完毕,出栈

  9. foo 函数执行完毕,出栈

  10. main 函数执行完毕,出栈

这种调用栈可以在程序报错的时候起到很好的 debug 的作用

function baz() {

throw new Error(“noop!”);

}

function bar() {

baz();

}

function foo() {

bar();

}

foo();

在查看错误中,我们明显的看到了之前提到的调用栈。

刚才的程序并无异步函数,

如果我们在程序中用到了异步函数

console.log(“begin”);

setTimeout(function cb(){

console.log(“finish”)

}, 1000);

这个时候我们再看执行栈

进栈出栈过程类似上面的分析,可是在这里,直到 main 函数执行完了,我们都没看到 cb 函数执行,可是确确实实 1000ms 左右后 cb 函数真的执行了,这里面是发生了什么情况?

在解释这个之前,我们先引入两个概念

宏观任务和微观任务

1. 宏观任务

在 ES5 之前,异步操作由宿主发起,JavaScript 引擎并不能发起异步操作,这类的异步任务称为宏观任务,比较典型的有

setTimeout(() => {

console.log(“exec”)

}, 2000);

2.微观任务

在 ES5 之后出现了 Promise ,用于解决回调地狱的问题,这个函数也是异步的,会等到 fulfill(resolve 或 reject) 后才会执行 then 方法

new Promise((resolve, reject) => {

resolve(“hello world”)

}).then(data => {

console.log(data)

})

这个异步任务,由 v8 引擎发起 称为微观任务

这两类任务对 event loop 也有影响

接下来进入本文章重点!!

event loop

event loop 分为浏览器环境和 node 环境,实现是不一样的,本篇文章暂时只讨论浏览器环境下的 event loop

1. 浏览器环境下的 event loop

接下来,我们具体看一个很大的例子

console.log(“1”);

setTimeout(function cb1(){

console.log(“2”)

}, 0);

new Promise(function(resolve, reject) {

console.log(“3”)

resolve();

}).then(function cb2(){

console.log(“4”);

})

console.log(“5”)

这段代码用 event loop 的解释是这样的

用文字解释如下,上述动画以及文字解释忽略 main 函数

  1. console.log("1") 入栈出栈,控制台显示 1

  2. setTimeout 入栈,加入异步任务队列(此时处于等待执行完成的状态,对于setTimeout来说就是等待延迟时间算执行完成,对于Promise 来说就是被 fulfill 了才算执行完成。

  3. new Promise 入栈出栈,控制台显示 3,并且把函数放入异步队列,等待完成了,就执行 then 方法,这里的话,演示动画忘记加上了。

  4. console.log(5) 入栈出栈,控制台显示 5

至此,主函数内的任务全部执行完毕,

这里需要先知道,当任务放入异步任务队列后他们如果完成了,就会自动进入微观任务或者宏观任务队列。

这个时候 event loop 检索微观任务队列是否有任务,如果有,就拖到 执行栈中执行,如果没有的话,就检索宏观任务队列是否有任务。

而且,如果一旦微观任务队列有任务,就一定会先执行微观任务队列的。

如果一旦执行栈有任务就一定会先执行执行栈的。

可以用代码表述如下

while (true) {

while (如果执行栈有任务) {

// 执行

}

if (微观任务队列有任务) {

// 执行

continue;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

你要问前端开发难不难,我就得说计算机领域里常说的一句话,这句话就是『难的不会,会的不难』,对于不熟悉某领域技术的人来说,因为不了解所以产生神秘感,神秘感就会让人感觉很难,也就是『难的不会』;当学会这项技术之后,知道什么什么技术能做到什么做不到,只是做起来花多少时间的问题而已,没啥难的,所以就是『会的不难』。

我特地针对初学者整理一套前端学习资料分享给大家,戳这里即可领取

前端路线图

!(备注:前端)**

最后

你要问前端开发难不难,我就得说计算机领域里常说的一句话,这句话就是『难的不会,会的不难』,对于不熟悉某领域技术的人来说,因为不了解所以产生神秘感,神秘感就会让人感觉很难,也就是『难的不会』;当学会这项技术之后,知道什么什么技术能做到什么做不到,只是做起来花多少时间的问题而已,没啥难的,所以就是『会的不难』。

我特地针对初学者整理一套前端学习资料分享给大家,戳这里即可领取

[外链图片转存中…(img-Rhj2a50v-1712566387497)]

vue.js的36个技巧

  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JS事件循环是指JS引擎在执行任务时的一种机制。在浏览器中,事件循环是由浏览器来实现的,而在NodeJS中也有自己的事件循环实现。事件循环的基本原理是将待处理的任务按顺序存放在一个任务队列中,然后从队列中取出任务并执行。在事件循环中,任务可以分为宏任务和微任务两种类型。宏任务包括整体的script代码、setTimeout、setInterval等,而微任务则包括Promise、MutationObserver等。在事件循环的执行过程中,微任务的执行优先于宏任务。 具体来说,事件循环的流程如下: 1. 执行当前的同步任务,即执行JS代码中的同步代码。 2. 检查是否存在微任务,如果存在,则按照先进先出的顺序依次执行微任务,直到微任务队列为空。 3. 当前的宏任务执行完成后,检查是否存在新的宏任务。如果存在,则执行下一个宏任务,否则继续等待新的任务加入队列。 4. 重复步骤2和步骤3,直到任务队列为空。 在NodeJS中,除了浏览器中的事件循环机制外,还有一些差异和新增的任务类型和任务阶段。具体来说,NodeJS事件循环包括以下几个阶段: 1. timers阶段:执行定时器回调函数。 2. pending callbacks阶段:执行延迟到下一个循环迭代的I/O回调函数。 3. idle, prepare阶段:仅在内部使用。 4. poll阶段:检索新的I/O事件;执行I/O相关的回调函数。 5. check阶段:执行setImmediate()的回调函数。 6. close callbacks阶段:执行关闭的回调函数,如socket.on('close', ...)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值