好吧,在我们开始之前,让我清理并承认本文的标题有点耸人听闻! JavaScript实际上没有多线程功能,JavaScript程序员无能为力。在所有浏览器中 - 除了Google Chrome - JavaScript都以单个执行线程运行,这就是它的方式。
> 但是,我们能做的是模拟多线程,这在多线程环境中带来了一个好处之一:它允许我们运行极其密集的代码。这是代码,否则将冻结浏览器并在Firefox中生成其中一个“反应式脚本”警告。> 钥匙要点
,但有时不是。有时根本无法避免特定操作的强度,而根本没有在JavaScript中进行。 在给定情况下,这可能是最好的解决方案;也许在应用程序中的某些处理需要移至服务器端,在该服务器端,它具有更多的处理能力,通常可以使用,以及真正的线程执行环境(Web服务器)。
>但最终您可能会发现这不是一个选择的情况 - JavaScript简单地
必须能够做某事或该死。这就是我在开发Firefox扩展时发现自己的情况。
该扩展名的核心是测试适用于页面的CSS选择器的能力,以查看是否实际使用它们。此的本质是使用Dean Edwards'Base2:
>肯定足够直接。但是agetall()本身非常强烈,就像它一样 - 要解析和评估任何CSS1或CSS2选择器,然后走整个DOM树寻找匹配;并且扩展程序是为
>
一个简单的测试用例for(var i=0; i<selectors.length; i++) <br> { <br> if(base2.DOM.Document.matchAll <br> (contentdoc, selectors[i]).length > 0) <br> { <br> used ++; <br> } <br> else <br> { <br> unused ++; <br> } <br> }
>让我们通过一个简单的测试案例来证明问题,涉及两个迭代级别;内部层面故意太密集,因此我们可以创建比赛条件,而外部层面相当短,因此它可以模拟主代码。这就是我们所拥有的:
>我们从简单的表单(这是测试代码,而不是生产)开始测试,并获取输出现在,让我们在Firefox中运行该代码(在这种情况下,在2GHz MacBook上使用Firefox 3)……并且正如预期的那样,浏览器UI在运行时冻结(例如,不可能,例如不可能按刷新并放弃该过程) 。大约90次迭代后,Firefox产生了一个“反应式脚本”警告对话框。
function process() <br> { <br> var above = 0, below = 0; <br> for(var i=0; i<200000; i++) <br> { <br> if(Math.random() * 2 > 1) <br> { <br> above ++; <br> } <br> else <br> { <br> below ++; <br> } <br> } <br> } <br> <br> <br> function test1() <br> { <br> var result1 = document.getElementById('result1'); <br> <br> var start = new Date().getTime(); <br> <br> for(var i=0; i<200; i++) <br> { <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [i=' + i + ']'; <br> <br> process(); <br> } <br> <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [done]'; <br> }
显然,在实践中我们无法运行代码。因此,让我们重新开始并使用异步计时器进行外循环:
>现在让我们再次运行……这一次我们会收到完全不同的结果。该代码需要一段时间才能完成,但是它可以一直成功地运行到末端,而没有UI冻结,并且没有警告过度缓慢的脚本。
for(var i=0; i<selectors.length; i++) <br> { <br> if(base2.DOM.Document.matchAll <br> (contentdoc, selectors[i]).length > 0) <br> { <br> used ++; <br> } <br> else <br> { <br> unused ++; <br> } <br> }
(繁忙的标志用于防止计时器实例发生碰撞。如果我们已经在下一次迭代时已经处于子过程中的中间,我们只需等待以下迭代,从而确保只有一个子过程一次运行。)
>因此,您可以看到,尽管我们可以在
> Inner过程中所做的工作仍然很小,但
的次数>我们可以运行该过程是无限的:我们可以运行该过程外循环基本上永远是永远的,浏览器将永远不会冻结。
>更喜欢它 - 我们可以在野外使用它。
>我已经可以听到反对者了。实际上,我可能自己是一个人:您为什么要这样做 - 什么样的疯子坚持将JavaScript推到从未被设计为去的所有这些地方?您的代码太强烈了。这是工作的错误工具。如果您必须跳过这类箍,那么您的应用程序的设计从根本上是错误的。
>我已经提到了一个例子,我必须找到一种繁重的脚本工作的方法。就是这样,或者整个想法必须放弃。如果您不相信该答案,那么本文的其余部分也可能对您不吸引您。>上的游戏
我在这里说的是了解游戏规则所需的代码,然后可以评估情况和策略,以便在该游戏中击败您。复杂的东西。
为了说明,我要看一个我在一边开发的项目一段时间。 “小时”是指三年,其中大多数是在理论上工作的高原上花费的,但太强烈了,无法使用……直到我想到了这种方法。该游戏是一个基于颜色和形状匹配的竞争难题。
>
总结一下:您通过相邻的形状和颜色匹配来整个过程。例如,如果您开始使用绿色三角形 - 那么您可以移至任何其他三角形或任何其他绿色形状。您的目标是到达中间的水晶,然后将其带到板的另一侧,而对手则尝试这样做。您也可以从对手那里窃取水晶。
因此,我们有确定运动的逻辑规则,我们还可以看到策略的出现。例如,为了避免让对手到达水晶,或从您那里偷走它 - 您可能会选择阻止它们的动作,或者尝试在他们无法到达的地方完成。
计算机的工作是在任何给定的情况下找到最佳的动作,因此让我们查看摘要伪代码中的该过程:>
for(var i=0; i<selectors.length; i++) <br> { <br> if(base2.DOM.Document.matchAll <br> (contentdoc, selectors[i]).length > 0) <br> { <br> used ++; <br> } <br> else <br> { <br> unused ++; <br> } <br> }
>每个策略功能都运行一个昂贵的过程,因为它必须评估董事会中的每个职位以及潜在的未来位置,可能会根据各种因素进行多次。该示例只有三种策略,但是在真实的游戏中,有数十种可能性,每个可能性都昂贵。
>>单独评估中的任何一个都很好,但是所有这些评估都可以连续运行,使过度激烈的过程冻结了浏览器。
>>因此,我所做的是将主代码拆分为“谨慎”任务
,每个任务都是用开关语句选择的,然后使用异步计时器进行迭代。这样做的逻辑距离那些小时候的那些选择您曾经有过的冒险书的逻辑不到一百万英里,在那里,每个任务都以实时的选择结束,直到我们到达终点:此代码比原始代码明显高得多,因此,如果减少代码大小是唯一的命令,这显然不是要走的路。
但是,我们在这里要做的是创建一个没有天花板的执行环境,即,在复杂性和长度方面没有上限的过程;这就是我们所做的。function process() <br> { <br> var above = 0, below = 0; <br> for(var i=0; i<200000; i++) <br> { <br> if(Math.random() * 2 > 1) <br> { <br> above ++; <br> } <br> else <br> { <br> below ++; <br> } <br> } <br> } <br> <br> <br> function test1() <br> { <br> var result1 = document.getElementById('result1'); <br> <br> var start = new Date().getTime(); <br> <br> for(var i=0; i<200; i++) <br> { <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [i=' + i + ']'; <br> <br> process(); <br> } <br> <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [done]'; <br> }
这个模式可以无限期地扩展
,具有数百甚至数千个任务。它可能需要很长时间才能运行,但是将其运行,并且只要每个个体
任务都不太强烈,它将在不杀死浏览器的情况下运行。无返回的路径
这种方法的强度也是它的主要弱点:由于内部函数是异步的,因此我们无法从外部函数中返回值。因此,例如,我们无法做到这一点(或者,我们可以,但没有意义): checksomething()函数将始终始终返回false,因为内部函数是异步的。外部功能将在内部功能的第一次迭代发生之前返回! 下一个示例同样毫无意义: >我们不超出外部功能的范围,因此我们无法从中返回;该返回值无用地消失在以太中。 我们的> 在这里做的是从AJAX编码技术中取出叶子,并使用回调函数(在此示例中,我称为“ oncomplete”): 因此,当我们调用checkSomething()时,我们将匿名函数作为其参数,并且当作业完成时,该函数以最终值调用: 优雅?不,但是功能强大吗?是的。这就是重点。使用此技术,我们可以编写原本不可能的脚本。 >在我们的套件中,我们现在有一种方法来解决以前摆脱可能性领域的JavaScript项目。我开发了这种模式的游戏具有相当简单的逻辑,因此一个相当简单的brain>,但对于常规迭代而言,它仍然太多了。还有很多其他游戏需要更多的影响力! 我的下一个计划是使用此技术实现JavaScript国际象棋引擎。国际象棋具有各种可能的场景和战术,导致决策可能需要很长时间才能计算,远远超过没有这种技术的可行性。即使创建最基本的思维机器也需要进行激烈的计算,我承认对可能性感到非常兴奋。 如果我们能像这样删除技巧,谁能说出可能?自然语言处理,启发式方法……也许我们有在JavaScript中开发人工智能的基础! >为什么javascript支持多本身? >在JavaScript中使用Web Worker进行多线程,您需要创建一个新的Worker对象并指定在工作线程中执行要执行的JavaScript文件。然后,您可以使用tostmessage方法与工作线程进行通信,并使用onMessage事件处理程序从其接收消息。 多插图可能会使您的JavaScript代码可能使您的JavaScript代码。更快,但这取决于要执行的任务的性质。对于CPU密集型任务,多线程可以通过允许并行执行任务来显着提高性能。但是,对于I/O结合的任务,多线程的好处不太明显,因为这些任务通常受到CPU控制以外的因素的限制,例如网络速度。for(var i=0; i<selectors.length; i++) <br>
{ <br>
if(base2.DOM.Document.matchAll <br>
(contentdoc, selectors[i]).length > 0) <br>
{ <br>
used ++; <br>
} <br>
else <br>
{ <br>
unused ++; <br>
} <br>
}
function process() <br>
{ <br>
var above = 0, below = 0; <br>
for(var i=0; i<200000; i++) <br>
{ <br>
if(Math.random() * 2 > 1) <br>
{ <br>
above ++; <br>
} <br>
else <br>
{ <br>
below ++; <br>
} <br>
} <br>
} <br>
<br>
<br>
function test1() <br>
{ <br>
var result1 = document.getElementById('result1'); <br>
<br>
var start = new Date().getTime(); <br>
<br>
for(var i=0; i<200; i++) <br>
{ <br>
result1.value = 'time=' + <br>
(new Date().getTime() - start) + ' [i=' + i + ']'; <br>
<br>
process(); <br>
} <br>
<br>
result1.value = 'time=' + <br>
(new Date().getTime() - start) + ' [done]'; <br>
}
<form action=""> <br>
<fieldset> <br>
<input type="button" value="test1" onclick="test1()" /> <br>
<input type="text" /> <br>
</fieldset> <br>
</form> <br>
function test2() <br>
{ <br>
var result2 = document.getElementById('result2'); <br>
<br>
var start = new Date().getTime(); <br>
<br>
var i = 0, limit = 200, busy = false; <br>
var processor = setInterval(function() <br>
{ <br>
if(!busy) <br>
{ <br>
busy = true; <br>
<br>
result2.value = 'time=' + <br>
(new Date().getTime() - start) + ' [i=' + i + ']'; <br>
<br>
process(); <br>
<br>
if(++i == limit) <br>
{ <br>
clearInterval(processor); <br>
<br>
result2.value = 'time=' + <br>
(new Date().getTime() - start) + ' [done]'; <br>
} <br>
<br>
busy = false; <br>
} <br>
<br>
}, 100); <br>
<br>
}
android shove silicon绵羊的梦想?
>
> javascript中多线程的限制是什么? 🎜>虽然可以通过Web Worker来实现JavaScript中的多线程,但重要的是要注意,这些工人无法访问DOM或其他Web API。它们仅限于几种可以来回发送到主线程的数据类型。另外,每个工人都是一个单独的实例,因此他们不共享范围或任何全局变量。
>如何在JavaScript中使用Web Worker进行多线程?
>多插图可以使我的JavaScript代码更快?
我可以在JavaScript中使用多线程进行前端开发吗? ,您可以在JavaScript中使用多线程进行前端开发。但是,重要的是要注意,启用多线程的Web工作人员无法访问DOM或其他Web API。因此,它们通常用于不涉及操纵DOM或与网页进行交互的任务,例如执行计算或处理数据。
以上是JavaScript中的多线程的详细内容。更多信息请关注PHP中文网其他相关文章!