在我深入探讨这个问题之前。让我声明,通过事件循环,我指的是 http://en.wikipedia.org/wiki/Event_loop .这是浏览器实现的东西。有关更多信息,请阅读:http://javascript.info/tutorial/further-javascript-features/events-and-timing-depth .
这个问题又难又长,所以,请耐心等待!我非常感谢所有的回答!
所以。现在,据我了解,在 JavaScript 中只有一个主线程(在大多数浏览器环境中)。所以,代码如下:
for (var color = 0x000; color < 0xfff; color++) {
$('div').css('background-color', color.toString(16));
}
会产生一个从黑到白的动画,但是你看不到,因为渲染是在代码处理完之后完成的(当下一个 tick 发生时——浏览器进入事件循环)。
如果你想看动画,你可以这样做:
for (var color = 0x000; color < 0xfff; color++) {
setTimeout(function() {
$('div').css('background-color', color.toString(16));
}, 0);
}
上面的例子会产生一个可见的动画,因为 setTimeout 将一个新事件推送到浏览器事件循环堆栈,该事件将在没有任何运行后进行处理(它进入事件循环以查看下一步要做什么)。
在这种情况下,浏览器似乎将 0xfff (4095) 事件推送到堆栈中,其中每个事件都通过它们之间的渲染进程进行处理。所以,我的第一个问题 (#1) 是渲染发生的确切时间?它总是发生在事件循环堆栈中两个事件的处理之间吗?
第二个问题是关于我给你的javascript.info网站链接中的代码。
...
function func() {
timer = setTimeout(func, 0)
div.style.backgroundColor = '#'+i.toString(16)
if (i++ == 0xFFFFFF) stop()
}
timer = setTimeout(func, 0)
....
我的问题是,浏览器是否会在每次到达 div.style 时将新的“渲染”事件推送到事件循环堆栈。 ... = ... 行?但是,由于 setTimeout 调用,它不会首先推送一个事件吗?那么,浏览器最终是否会像这样出现在堆栈中:
setTimeout event
render event
因为在 div 样式更改之前处理了 setTimeout 调用?如果这就是堆栈的样子,那么我会假设下一次浏览器进入事件循环时,它将处理 setTimeout 的回调并最终得到:
rendering event
setTimeout event
rendering event
并继续之前的 setTimeout 调用产生的渲染事件?
最佳答案
Q1:不一定。浏览器在不同程度上实现了优化。例如,他们可能会等待收集几个样式更改,然后再触发代价高昂的布局重新计算。所以答案是:取决于具体的浏览器。
试试这个:http://taligarsiel.com/Projects/howbrowserswork1.htm#Render_tree_construction (该文档的日期为 2009 年 10 月 - 即它是最新的)
Q2:渲染不一定和JS执行一样——那是两个不同的引擎。这个 JS 引擎不负责渲染,它只是与渲染引擎交互。在我看来,第二个问题的主要信息是JS 与渲染引擎的独立性。请记住,浏览器(或网页)不需要 Javascript,它们的主要目的是根据 CSS 样式规则呈现 HTML。 Javascript 只是操作 HTML(实际上是 DOM 树)和样式规则的一种方式。
请注意,您可以通过读取样式定义来强制渲染 - 此时渲染引擎别无选择,只能处理任何未完成的样式更改,尤其是当它涉及任何位置更改时。这就是为什么在进行大量样式更改或添加大量元素(例如,当大量行被一一添加(“for”循环)到表中时。
根本不是问题的一部分 - 但由于我刚刚提到了 display:none 和 visibility:hidden 之间的区别,这也是添加 hidden position:absolute 元素(如对话框)时的一个考虑因素。虽然绝对定位的元素是否使用一种或另一种方法对您隐藏没有明显的区别,但在内部有很大的区别:当使用 visibility:hidden 隐藏时,元素是渲染树的一部分,而 display:none 则是不是。因此,如果有这样一个需要多次切换的元素,则应该使用 visibility:hidden,因为当“显示”样式在“无”和例如“显示”之间切换时。 “阻止”浏览器必须首先呈现它。
关于javascript - 我不完全理解 JavaScript 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5203738/
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
我是ruby的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭3年前。Improvethisquestion我正处于学习Ruby的阶段,我想查看一些小型库的源代码以了解它们是如何构建的。我不知道什么是小型图书馆,但希望SO能推荐一些易于理解的图书馆来学习。因此,如果有人知道一两个非常小的库,这是新手Rubyists学习的好例子,请推荐!我想使用Manveru'sInnatelib,因为它试图保持在2000LOC以下,但我还不熟悉其中经常使用的Ruby速记。也许大约100-5
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
我有一个使用PDFKit呈现网页的pdf版本的Rails应用程序。我使用Thin作为开发服务器。问题是当我处于开发模式时。当我使用“bundleexecrailss”启动我的服务器并尝试呈现任何PDF时,整个过程会陷入僵局,因为当您呈现PDF时,会向服务器请求一些额外的资源,如图像和css,看起来只有一个线程.如何配置Rails开发服务器以运行多个工作线程?非常感谢。 最佳答案 我找到的最简单的解决方案是unicorn.geminstallunicorn创建一个unicorn.conf:worker_processes3然后使用它:
由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A
所以,Ruby1.9.1现在是declaredstable.Rails应该与它一起工作,并且正在慢慢地将gem移植到它。它具有native线程和全局解释器锁(GIL)。自从GIL到位后,原生线程是否比1.9.1中的绿色线程有任何优势? 最佳答案 1.9中的线程是原生的,但它们被“放慢了速度”,一次只允许一个线程运行。这是因为如果线程真的并行运行,它会混淆现有代码。优点:IO现在在线程中是异步的。如果一个线程阻塞在IO上,那么另一个线程将继续执行直到IO完成。C扩展可以使用真正的线程。缺点:任何非线程安全的C扩展都可能存在使用Thre