JavaScript事件循环同步任务与异步任务怎么实现

执行栈与任务队列

执行栈

  • 姑且先不说执行栈是什么,先说栈是什么吧。栈就好似一个桶,最先放入的东西肯定是最后拿出来的,就是大家常说的先进后出。

JavaScript事件循环同步任务与异步任务怎么实现

那么执行栈就是把图中的内容块变成代码任务,光说肯定说不明白,还是得上代码:

function fn (count) {            if (count <= 0) return            fn(count - 1)            console.log(count)        }fn(3)

这是一段很简单的递归代码,这里我们直接上图解释(这里其实画的不严谨,栈底应该是全局执行上下文):

JavaScript事件循环同步任务与异步任务怎么实现

js中所有的任务都会在主线程上执行然后形成一个执行栈(请记住这一点!!!)

任务队列

那么队列和栈则是相反的,队列是先进先出的。其实很好理解,和我们平时排队是一个道理,先进入队伍的人肯定先出来。那么任务队列通俗理解就是用来放置异步任务的回调函数的(也请记住这一点!!!)

同步任务与异步任务

先上一点概念性的东西,打个基础:

同步任务

很多人在理解同步任务的时候会被它的语义搞混,其实同步任务不是同步一起执行的。它是要等待上一个执行任务结束才可以执行下一个任务,这里说起来也并不晦涩难懂,但是还是写段简单的代码解释一下:

console.log(1)console.log(2)console.log(3)

代码很简单吧,很明显输出结果是1,2,3,这就是同步代码,那么我们就可以总结了,同步任务就是在主线程上面排队,然后一个一个进入执行栈执行,直到执行栈为空。

异步任务

还是直接举个栗子:

console.log(1)setTimeout(() => {    console.log(2)}, 1000)console.log(3)

这段代码的输出和上面同步代码的输出不一样,它的输出顺序是1,3,2,这就是异步代码,它并不会按照执行顺序去执行,

同样我们用官方话语总结一下:异步任务指的是,不进入主线程、而进入”任务队列”(Event queue)的任务,只有”任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行 如果不理解没有关系,后面说到了事件循环就会醍醐灌顶了。

js的执行机制

先上比较晦涩难懂的概念:

  • 1. 同步任务由JavaScript 主线程按顺序执行。

  • 2. 异步任务委托给宿主环境执行。

  • 3. 异步任务完成后,对应的回调函数会被加入到任务队列中等待执行,任务队列又被分为宏任务队列和微任务队列,优先执行微任务队列,常见的微任务有new Promise().then,常见的宏任务有定时器

  • 4. JavaScript 主线程的执行栈被清空后,会读取任务队列中的回调函数,次序执行。

  • 5. JavaScript 主线程不断重复上面的第4 步,在执行回调函数时又会按照上面的四步去执行。

js一直从任务队列中取回调函数,然后放入主线程中执行,这是一个循环不断的过程,所以把它叫做事件循环。

这个还是要简单粗暴的来段代码会更直观一点:

const promise = new Promise((resolve, reject) => {      console.log(1);      setTimeout(() => {          console.log("timerStart");          resolve("success");          console.log("timerEnd");       }, 0);      console.log(2);  });  promise.then((res) => {      console.log(res);  });  console.log(4);

现在我们根据上面的规则一步一步分析这段代码,如果不懂Promise也没有关系,我保证这并不影响你对事件循环的理解。现在你就把自己当成js代码的检察官,要正确把它们放在合适的“位置”

  • 检察官的名列前茅步就是判断哪些是同步代码,哪些是异步代码,OK,首先从上往下看,Promise本身是同步的,所以它应该在主线程上排队,然后继续看pomise.then是个异步任务,并且是属于微任务的,它的回调函数应该在微任务队列中(此时还不在),最后一句输出语句是同步代码,应该在主线程上排队。

  • 第二步,执行主线程上的同步代码,首先有Promise排着队呢,所以先输出1,随后有个定时器,所以应该把它挂起执行,由于它没有时间延迟,所以回调函数直接被放入宏任务队列,继续执行代码,遇到打印,直接输出2。现在主线程还有其他的同步代码不?是不是还有一个输出语句,所以输出4,现在主线程上的同步代码执行完了

  • 第三步读取任务队列,由于微任务队列上没有东西(Promise的状态并没有改变,不会执行promise.then()),所以读取宏任务队列上的回调函数,回调函数进入主线程执行,首先输出timerStart,然后promise状态发生改变,然后又遇到一个输出语句,输出timerEnd。现在主线程上又没有东西了,又得去看任务队列上有没有东西了。

  • 第四步,由于promise状态发生改变了,所以微任务队列上有回调函数了,执行输出语句,res为success,输出success

关于“JavaScript事件循环同步任务与异步任务怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。

文章标题:JavaScript事件循环同步任务与异步任务怎么实现,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/22257

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云的头像亿速云认证作者
上一篇 2022年9月1日 下午11:17
下一篇 2022年9月1日 下午11:18

相关推荐

  • Java基于面向对象如何实现一个战士小游戏

    一、思路 首先,我们知道在系统中有个战士的角色叫Soldier,Soldier角色拥有自己的名字、等级、生命力、攻击力、防御力。我们就要区分有什么类型。战士有个行为是普通攻击,行为:方法。由此我们就知道到战士Soldier是一个类,在进行代码实现。 二、代码实现 当我们得知Soldier属于一个类是…

    2022年9月6日
    60400
  • 如何进行授权的APK渗透测试

    作为一个渗透测试小白,本文的目的是希望能为那些和我一样的小白提供一些测试思路。涉及的内容可能比较基础,表哥们见谅。APK 解包拿到 apk 之后直接用 7-Zip 解压可以得到几个文件夹、一个 AndroidManifest.xml 文件、一个dex文件。使用 dex2jar https://sou…

    2022年9月18日
    51700
  • java源文件的扩展名是哪个

    java源文件扩展名是“.java”;用javac进行编译,生成后缀名为“.class”的字节码文件,保存在和源程序一致的目录下,如源代码有错误,会按行指出错误,修改错误后重新进行编译,直至生成“.class”字节码文件为止。 本教程操作环境:windows7系统、java10版、DELL G3电脑…

    2022年8月27日
    84800
  • 如何解决1045无法登录mysql服务器

    解决方法:1、找到“my.ini”系统配置文件,把“skip-grant-tables”放在“port=****”下面;2、如果放在C盘里,那么需要编辑权限,并保存修改;3、打开MySQL数据库之前先重启服务,打开cmd命令提示符,直接输入mysql,回车打开MySQL数据库即可。 本教程操作环境:…

    2022年9月6日
    78100
  • C#非托管泄漏中HEAP_ENTRY的Size为什么会对不上

    一:背景 1. 讲故事 前段时间有位朋友在分析他的非托管泄漏时,发现NT堆的_HEAP_ENTRY 的 Size 和 !heap 命令中的 Size 对不上,来咨询是怎么回事? 比如下面这段输出: 0:000> !heap 0000000000550000 -aIndex Address Na…

    2022年9月22日
    51300
  • 关于远程办公,微软MVP 15年研发团队的经验分享

    为了能够应对来势汹汹的疫情,众多互联网企业纷纷开启了远程办公模式。不知道各团队前两天的远程办公效果如何,我们 Worktile 管理层在大年初四就开始讨论远程办公的事情,并且将可能出现的问题都尽量提前想到并做了准备。从这两天实际执行的情况看,我所在的研发团队执行的还不错,基本没有受到什么明显的影响。…

    2022年3月20日
    38000
  • windows会声会影如何导出视频x9

    会声会影导出视频x9的方法 1、首先点击图示位置的“共享”按钮。 2、然后在图示框中选择想要导出的视频格式。 3、在图示位置可以调整具体参数。 4、最后点击“开始”就可以了。 以上就是“windows会声会影如何导出视频x9”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,…

    2022年9月15日
    50700
  • 如何进行Web权限维持分析

    前言 权限维持,在红蓝对抗中,我觉得其意义在于两点:一是防止已获取的权限被蓝队破坏;二是防止其他红队获取到相同的权限(虽然有点缺德。。。)。 其他情况下的非法用途就不说了。 权限维持的原则我觉得就是不能影响原来业务的正常运行。(比如改后台密码导致管理员不能登录,修改文件夹读写权限导致正常的文件不能上…

    2022年9月24日
    49100
  • jquery ajax如何改成同步

    在jquery中,ajax可以将async设置为false使其同步;默认情况下jquery中的ajax为异步请求,即“async:true”,通过设置参数“asycn:false”即可,语法为“$.ajax({async: false})”。 本文操作环境:windows10系统、jquery3.6…

    2022年9月10日
    2.4K00
  • unity发布出来的安卓apk该如何加密

    Unity3D程序的安全问题 代码安全问题 Unity3D 程序的核心程序集文件 Assembly-CSharp.dll 是标准的 .NET 文件格式,附带了方法名、类名、类型定义等丰富的元数据信息,使用 DnSpy 等工具可以轻易地将其反编译和篡改,代码逻辑、类名和方法名等一览无余。代码逻辑一但被…

    2022年9月13日
    87300
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部