当前位置: 首页 > 网络应用技术

什么,仍然有些人不了解JavaScript的事件循环机制。

时间:2023-03-05 21:25:26 网络应用技术

  每个人都知道JavaScript是一种单线语言,一次只有一件事。

  至于为什么它是一个线程,它实际上与使用相关。由于JavaScript作为Goggles脚本语言,其主要目的是与用户进行交互并操作DOM。如果是多线程,则该线程删除一个线程DOM,另一个线程添加了此DOM的内容或修改。此时如何渲染?

  因此,从诞生开始,JavaScript是单个线程,是该语言的核心功能。

  当然,HTML5提出了Web Worker标准,以允许JavaScript脚本创建多个线程,但是子线程由主线程控制,无法操作。该标准不会改变单个线程的本质。

  一个线程的特征将引起一些问题,例如:当我们请求服务器接口时,该页面在等待数据返回之前就无法操作,并且会有假死亡的状态。但实际上,我们确实做到了没有遇到这种情况。

  这是因为我们通过异步(非屏体)执行模式解决了单线线程的问题。

  同步(阻止)

  当涉及异步时,我们自然可以考虑同步(阻止)。

  什么是同步?好像我们要排队核酸。Dabai通过排队的顺序进行了测试。背后的人只能等待前面的人们检测到它以检测到它。

  上述代码将按顺序执行,当时它将输入循环。大约2秒钟后,它将跳出循环,然后执行最后一行打印行。这导致了阻塞的出现。封锁的特征是:遇到时间 - 耗时代码片段,消耗时间的代码已完成继续代码继续执行。

  异步(非块)

  异步和同步,它不会阻止程序的操作。当程序运行时,当遇到异步模式的代码时,引擎将挂起异步任务并首先跳过,然后继续执行非 -特定代码。执行同步代码时,刚刚悬挂的异步代码按特定顺序执行。我们可以查看以下代码:

  该程序将首先输出,然后等待2秒钟输出。由于程序执行时,当我遇到SetteMeTimeout时,它不会直接执行内部回调函数。取而代之的是,首先悬挂内部函数,继续执行以下同步代码,在执行同步代码后,请等待大约2秒钟,然后回头回去。

  可以想象异步。您必须去超市购买食物。您无法想到做一次菜一次买菜。列出,但列出了菜肴。

  JavaScript的运行顺序是严格的一个线程异步模式:前面的同步,在后面的异步。异步任务需要等待在执行之前执行当前同步任务。

  尽管游客是由单个线程执行以执行JavaScript代码的,但游客有多个线程,可以帮助操作实现单个线程异步模型。

  在运行JavaScript代码的过程中,实际执行实际执行程序时只有一个活动线程,并且通过多线程切换来实现同步异步。

  以上段线程可以汇总到两个线程中:

  在上面,我们将线程分为主线程和工作线程。当主线程的代码运行时,当同步代码运行时,我们将其放在执行堆栈中以execute.rise。

  执行堆栈负责执行代码,遵循高级和输出的原理,当执行功能时,它将按顺序从外部到内部运行。对象的数据可以存储在堆内存中。

  悬挂在工作线程中的任务都是异步任务,例如网络请求,定时功能,交互式事件等。

  当执行堆栈中的任务完全执行时,执行堆栈是明确的,并且事件周期将开始工作。它将检测到消息队列中是否有任务。插入已过期的异步任务到达消息队列中。如果需要执行一个任务,则将按照反盗窃执行堆栈执行,按先进的首先,直到消息队列也为空。

  如上所述,定义了5个函数。执行后,主要程序首先遇到了两个异步任务。在0秒后,F5和F6在1秒后执行。键(即将其放入工作线中),然后继续下面的代码。

  然后,F1函数首先输入执行堆栈执行,并从堆栈中执行F1函数。

  然后将F2函数放入执行堆栈执行中,然后将F2函数从堆栈中执行。

  然后将F4函数放在执行堆栈执行中。执行F4函数时,发现F3函数将在内部执行。此时,将F3函数放在执行堆栈中以执行。

  当主线程的同步代码完全执行时,此时,事件循环机制将起床并起作用,并继续从消息队列中读取是否需要执行任务。

  下一步是执行异步任务。现在,我们有3个异步任务要执行,F5需要0秒,F6需要1秒,而打印123的任务也需要0秒。

  尽管F5和打印123的任务时间相同,但F5的任务比打印123优先考虑工作线程,因此F5将优先考虑输入消息队列。

  目前,事件周期机制发现消息队列中有一个任务,并且F5将在执行堆栈中取出以执行然后退出堆栈。

  然后将123的任务打印到执行堆栈中。执行后,发现还有另一个异步任务打印1234,它将将此异步任务放入工作线程中,然后执行堆栈。

  打印1234异步任务的所需时间为0秒,它将输入消息队列优先级,而不是F6,然后通过入射周期机制取出。

  F6进入消息队列后,这也是如此。直到新闻队列为空。

  执行堆栈:执行根据后续条目的顺序输入执行堆栈的任务,并在执行后离开堆栈。

  工作线程:停滞异步任务悬挂,首先是在时间顺序上,到达哪个任务时间,然后将任务放在消息队列中。如果有相同的时间,请按顺序以输入工作线程顺序输入消息队列。

  事件周期机制:执行同步代码后,任务是从消息队列(高级第一)中持续采取的,然后放入执行堆栈执行中。

  从上面的内容可以看出,当我们运行单层函数时,堆栈执行该功能,然后将其从堆栈中销毁。turn.但是,如果有规范,则将堆栈框架堆叠在执行堆栈中。

  如上所示,执行程序后,Test1将输入执行执行堆栈,然后执行执行时,发现Test1调用FN,FN,FN将传递。然后Test1将停止;

  执行Test2时,您会发现Test3在Test2中调用,然后将Test3放置在堆栈顶部。

  执行Test3后,它将退出堆栈,然后继续执行Test2。执行Test2后,它将退出堆栈,并将继续测试1。

  目前,我们将考虑递归。递归函数可以被视为函数中的嵌入式n层执行。在执行过程中,将触发大量的堆栈框架积累,但是执行堆栈是深度。过多的堆栈框架积累会导致堆栈溢出。

  根据不同的游客和JS发动机,堆栈的深度将有所不同。

  如下所示,我们发现在递归11390次之后,提示它超过了堆栈的深度。

  如何打破递归限制。目前,我们可以探索如何跨越示意力的限制?

  我们之前说,在执行堆栈中执行程序后,事件周期机制将启用。如果执行堆栈在执行时遇到异步任务,则异步任务将悬挂在工作线程上,然后遵循以下内容-up -up -up -up -up代码将继续。

  因此,我们可以将递归执行函数放在异步任务中吗?以这种方式,堆栈的堆栈不会累积堆栈框架。每次您仅从消息队列中删除任务时,递归调用的任务都放在工作线中,继续执行同步代码后继续执行以下同步代码,然后读取消息的queueThe queueThe queueThe queueThe queuether osynchronous任务中期到期的执行堆栈中,并反复。

  针不戳,但不能保证操作速度。

  在这一点上,至于宏任务和微任务,让我们稍后再谈谈!

  原始:https://juejin.cn/post/7097518995620200485