大家好,今天来为大家解答js 时间循环这个问题的一些问题点,包括js中事件循环的理解也一样很多人还不知道,因此呢,今天就来为大家分析分析,现在让我们一起来看看吧!如果解决了您的问题,还望您关注下本站哦,谢谢~
本文目录
一、聊一聊浏览器事件循环与前端 *** 能
1、在网上也看了不少关于j *** ascript事件循环的文章,多数是以浏览器事件循环与nodejs中事件循环做对比,分析两种环境的差异。下面说的内容是浏览器事件循环与前端 *** 能之间的关系,了解之后在开发中规避一些 *** 能问题。以下所探讨的事件循环皆指浏览器的事件循环,本文属于个人理解,如有不对欢迎提点。
2、 提到事件循环,相信现在多数前端小白并不陌生了。首先事件循环分为宏任务和微任务。
3、宏任务:鼠标事件,键盘事件, *** 事件,Html解析,定时器等;
4、 当这些事件发生的时候浏览器会在对应的事件队列(宏任务队列和微任务队列)中添加该事件处理器(回调函数)等待执行。而事件循环是一直循环着看事件队列中是否还有未处理的处理器,如果有的话就从队列首位取出处理器执行,执行完之后就移除对应处理器,就是这样一直循环着直到浏览器关闭为止,即使事件队列为空!但是在处理宏任务队列和微任务队列的方式不同。
5、在一次事件循环中只能处理一个宏任务,而需要处理所有微任务直到微任务队列清空
6、说明:事件循环是在主程序执行完之后就开始循环执行事件,主程序说简单点就是一个js文件从之一行执行到最后一行,主程序结束(此处说的是该应用就一个js文件)
7、 银行中排队办理业务的时候,假设每个排队等待办理的普通客户是宏任务,而VIP客户是微任务。那么在银行早上开始上班的之前,柜员启动相应的机器(电脑,打印机等)属于主程序,等一切准备好之后就开始办理业务了。假如现在有10个普通用户(宏任务)在等待,开始处理之一个客户,处理完之后叫号第二个客户,开始处理。如果在处理第二个客户的时候突然来个一个vip用户,那么在处理为完普通用户之后就轮到处理VIP用户(微任务),如果在处理VIP用户的时候又来了个VIP用户的话3号普通客户就得等待处理完两个VIP客户。当然此处举例皆是只该银行就一个服务窗口,复合js单线程模式。
8、 浏览器通常会尝试60秒渲染一次页面,以达到每秒60帧(60fps)的速度, 60fps是检验前端体验是否流畅的标准,在动画里就意味着当浏览器没16ms一次刷新的话,体验是最流畅的,所有在整个页面生命周期中每一次事件循环都应该在16ms内完成。
9、但是在事件循环中可能会处理比较耗时的任务,那么渲染就会延后这样就会导致动画看上去不流畅,更严重的可能是页面处于假死状态等影响用户体验。
10、如果加上UI渲染的话上面的事件循环图是这样的
11、 上面提到浏览器会尝试16ms重新渲染页面,那么假如在处理事件的时候遇到耗时任务的时候,浏览器将会延迟渲染页面,如果处理不当那将会导致体验差问题。接下来仔细分析以下整个流程。
12、 首先先排除为任务,只有宏任务的程序。现在有两个点击事件
13、假如主线程运行需要15ms,btn1事件处理器完成需要8ms, btn2需要10ms;那么整个流程是这样:
14、假如用户点击速度很快的时候,主线程运行期间在5ms和12ms时候分别点击了btn1,btn2按钮,触发点击事件,此时因为还处与主线程运行时间内,所有此时会向宏任务队列添加两个事件任务。当主线程运行到15ms时结束,此时浏览器可以重新渲染。渲染完之后进入事件循环,首先从任务队列中取出任务btn1事件处理器执行,此过程会耗时8ms,处理完之后结束一次事件循环,并移除事件处理器btn1。此时浏览器可以重新渲染,渲染完之后又进行到第二次事件循环,重复上述步骤,直到事件队列清空为止。
15、 如果事件循环中存在为任务的话流程如下:
16、其实只是在宏任务之后加入了一个时间段处理为任务.。在之一循环中处理btn1事件处理器时添加promise1到微任务队列中,在执行完btn1事件之后检查微任务队列发现有一个任务待处理,然后取出处理之后移除微任务promise1在循环微任务队列,发现以微任务队列为空,28ms时浏览器可以重新渲染(此时浏览器距离上次渲染相差12ms,渲染流畅)。在执行第二次事件循环的时候,在执行到微任务队列时,需要处理两个任务,耗时8ms,46ms时浏览器可以重新渲染(此时浏览器距离上次渲染相差18ms,渲染流畅)。
17、总结:如果在事件循环中有的任务比较耗时,会导致浏览器渲染fps变小,从而导致用户体验差。如向页面中 *** 10000个td节点的时候,如果是一次循环就appendChild一次,那相当于总共会有10000个微任务待执行,这样就会影响到浏览器渲染的fps,所有会出现点击页面没有反响的体验,这就是为什么 *** 多个节点需要拼接到一起一次 *** *** 节点。了解事件循环和浏览器渲染之间到联系之后,以后开发多注意一些耗时任务到处理,到此分享结束。
二、我的世界playsound指令如何循环播放
您好!这里没有高明的指令,因为到目前1.8为止,没有任何的检测playsound结束的 *** 。但是我有高明的电路来帮你简化延迟2分钟。如果你想 *** 一个延迟,我为你推荐2种 *** 。
*** 简单易懂,你自己试一下就知道了(两个活塞都是粘 *** 的,两个漏斗是相对放置的,放置时先放一个,然后按住shift右键原先放的放置第二个即可)
漏斗里东西越多,循环一次的时间越长,能非常方便的做延迟。这样你就不用放300个中继器了。
暂停他的方式是在漏斗上放置红石块,不过可控 *** 差
这个是用到了指令的电路,主要运用scoreboard做计时
1、【/scoreboard objectivesadd js1 dummy计时1】
首先输入这个指令建立一个用来计时的变量js1
2、【/scoreboard objectives setdisplay sidebar js1】
然后输入这个指令把js1添加到右侧显示位,方便我们观察
添加后不会直接显示出来,因为js1还没有值,赋值后就会显示出来
3、【/gamerule com *** ndBlockOutput false】
为了防止待会儿被命令方块刷屏,我们先输入这个指令
可以观察到右边有个记分板,那是因为我已经执行过一次了,赋值过了,所以显示出来了。
【scoreboard players add@a js1 1】每次执行给js1+1
【testfor@a[score_js1_min=100]】不断的检测js1是否到达了100,这个数你可以自己根据需要的延迟大小调整,是核心部分。达到后计时结束,用比较器输出激活右面的两个
【setblock 122 67-146 air】这里我这个坐标是左边的比较器下面那格的坐标,就是放置红石块的坐标,用来在计时完毕后移出红石块把高频停止
【scoreboard players set@a js1 0】重置记分板js1,方便下一次的激活
每次激活的时候只需要在比较器下面那一格放置红石块开启高频即可,可以使用setblock指令来完成。这种计时虽然麻烦,但是可控 *** 极强,可以随时停止,随时重置,而且可以计时很长时间。而漏斗时钟非常不方便,而且最多放置4× *** 个物品,再多就不行了。不过用来完成你要的效果绰绰有余了。
鉴于你是需要循环播放,可以不输入移除红石块的指令(第三个),直接一次一次的循环。
一定要记住,命令并不是万能的,红石也不是万能的。只有红石和命令结合起来,才能实现各种各样神奇的效果。要做个好的地图 *** 者,不仅要会命令方块,更要会红石。
三、Node.js setTimeout在while循环中不起作用
1、被调用时,它会在指定的时间后将回调函数添加到事件循环队列中。在while
2、循环中,由于代码在循环中被同步执行,事件循环被阻塞,因此setTimeout
3、中指定的回调函数不会被添加到事件循环队列中,直到循环结束。
4、,则所有的回调函数都会在循环结束后立即执行,而不是在指定的时间后执行。
5、为了解决这个问题,可以考虑使用
6、放在异步函数中执行,以确保回调函数被添加到事件循环队列中。例如:
7、function doSomething(){// do something... setTimeout(function(){// do something after 1000ms...}, 1000);}//异步函数中执行 setTimeoutasync function doSomethingAsync(){// do something... await new Promise(resolve=> setTimeout(resolve, 1000));// do something after 1000ms...}
OK,关于js 时间循环和js中事件循环的理解的内容到此结束了,希望对大家有所帮助。