搜索
首页web前端js教程JavaScript中的多线程

JavaScript中的多线程

好吧,在我们开始之前,让我清理并承认本文的标题有点耸人听闻! JavaScript实际上没有多线程功能,JavaScript程序员无能为力。在所有浏览器中 - 除了Google Chrome - JavaScript都以单个执行线程运行,这就是它的方式。

> 但是,我们能做的是模拟

多线程,这在多线程环境中带来了一个好处之一:它允许我们运行极其密集的代码。这是代码,否则将冻结浏览器并在Firefox中生成其中一个“反应式脚本”警告。> 钥匙要点

JavaScript

>不本质地支持多线程,而是通过异步计时器和网络工作人员进行模拟,允许密集的计算而无需冷冻浏览器。
    >异步计时器将任务分解为较小的块,从而通过管理代码如何随着时间的推移来执行方式来防止浏览器变得无响应。
  • >
  • > Web工作者增强了JavaScript执行背景任务而不会影响用户界面的能力,尽管他们无法与DOM进行交互或使用某些Web API。
  • 对于冒着锁定浏览器的复杂操作,使用异步计时器进行重构代码可以防止UI冻结并更有效地管理资源密集型过程。
  • 尽管JavaScript具有单线程的性质,但诸如异步编程和网络工作人员之类的技术为开发人员提供了强大的工具来处理多线程式的方案,从而提高了强化任务的性能。
  • 时间等待没有一个人
  • >这一切都取决于使用异步计时器的使用。当我们在异步计时器中运行重复代码时,我们将为浏览器的脚本解释器处理每次迭代的时间。
  • > 有效地,迭代器中的一块代码正在要求解释器立即完成所有操作:“运行此代码 n
  • 尽可能快地运行。”但是,异步计时器内的相同代码将代码分解成小谨慎的块。也就是说,“运行此代码一次尽可能快”,然后等待 - 然后“尽可能快地运行此代码”,依此类推,
诀窍是,每次迭代内部的代码都很小且简单,以使解释器在计时器速度(无论是100或5,000毫秒)的速度以内处理。如果满足了该要求,那么整体代码的强度都没有关系,因为我们并不要求一次运行它。

>

“太激烈”多么激烈?
> 通常,如果我编写一个被证明太密集的脚本,我会考虑重新设计它;这样的显着放缓通常表明代码存在问题,或者是应用程序设计的更深层次问题。

,但有时不是。有时根本无法避免特定操作的强度,而根本没有在JavaScript中进行。 在给定情况下,这可能是最好的解决方案;也许在应用程序中的某些处理需要移至服务器端,在该服务器端,它具有更多的处理能力,通常可以使用,以及真正的线程执行环境(Web服务器)。

>但最终您可能会发现这不是一个选择的情况 - JavaScript简单地

必须

能够做某事或该死。这就是我在开发Firefox扩展时发现自己的情况。 该扩展名的核心是测试适用于页面的CSS选择器的能力,以查看是否实际使用它们。此的本质是使用Dean Edwards'Base2:的Matchall()方法的一组评估

>肯定足够直接。但是agetall()本身非常强烈,就像它一样 - 要解析和评估任何CSS1或CSS2选择器,然后走整个DOM树寻找匹配;并且扩展程序是为的每个单独的选择器的,其中可能有几千个。表面上如此简单,该过程可能是如此密集,以至于整个浏览器发生在发生时。这就是我们发现的。

锁定浏览器显然不是一个选项,因此,如果这根本无法使用,我们必须找到一种使它运行而不会出错的方法。

>

一个简单的测试用例
for(var i=0; i<selectors.length i>
{ <br>
  if(base2.DOM.Document.matchAll <br>
    (contentdoc, selectors[i]).length > 0) <br>
  { <br>
    used ++; <br>
  } <br>
  else <br>
  { <br>
    unused ++; <br>
  } <br>
}</selectors.length>

>让我们通过一个简单的测试案例来证明问题,涉及两个迭代级别;内部层面故意太密集,因此我们可以创建比赛条件,而外部层面相当短,因此它可以模拟主代码。这就是我们所拥有的:

>我们从简单的表单(这是测试代码,而不是生产)开始测试,并获取输出

现在,让我们在Firefox中运行该代码(在这种情况下,在2GHz MacBook上使用Firefox 3)……并且正如预期的那样,浏览器UI在运行时冻结(例如,不可能,例如不可能按刷新并放弃该过程) 。大约90次迭代后,Firefox产生了一个“反应式脚本”警告对话框。

function process() <br>
{ <br>
  var above = 0, below = 0; <br>
  for(var i=0; i
  { <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
  { <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>
}
如果我们允许它继续下去,在另外90个迭代后,Firefox再次产生相同的对话框。在这方面,Safari 3和Internet Explorer 6的行为类似,并具有冻结的UI和一个警告对话框的阈值。在Opera中没有这样的对话框 - 它只是继续运行代码直到完成代码 - 但是浏览器UI类似地冻结了直到完成任务。

显然,在实践中我们无法运行代码。因此,让我们重新开始并使用异步计时器进行外循环:>

>现在让我们再次运行……这一次我们会收到完全不同的结果。该代码需要一段时间才能完成,但是它可以一直成功地运行到末端,而没有UI冻结,并且没有警告过度缓慢的脚本。

for(var i=0; i<selectors.length i>
{ <br>
  if(base2.DOM.Document.matchAll <br>
    (contentdoc, selectors[i]).length > 0) <br>
  { <br>
    used ++; <br>
  } <br>
  else <br>
  { <br>
    unused ++; <br>
  } <br>
}</selectors.length>
>查看测试页面

(繁忙的标志用于防止计时器实例发生碰撞。如果我们已经在下一次迭代时已经处于子过程中的中间,我们只需等待以下迭代,从而确保只有一个子过程一次运行。)

>因此,您可以看到,尽管我们可以在

> Inner

过程中所做的工作仍然很小,但

的次数>我们可以运行该过程是无限的:我们可以运行该过程外循环基本上永远是永远的,浏览器将永远不会冻结。 >更喜欢它 - 我们可以在野外使用它。 你疯了!

>我已经可以听到反对者了。实际上,我可能自己是一个人:您为什么要这样做 - 什么样的疯子坚持将JavaScript推到从未被设计为去的所有这些地方?您的代码太强烈了。这是工作的错误工具。如果您必须跳过这类箍,那么您的应用程序的设计从根本上是错误的。

>我已经提到了一个例子,我必须找到一种繁重的脚本工作的方法。就是这样,或者整个想法必须放弃。如果您不相信该答案,那么本文的其余部分也可能对您不吸引您。

>但是,如果您是 - 或者至少,如果您愿意说服它,这是另一个真正可以将其钉在家里的示例:使用JavaScript编写可以在计算机上进行比赛的游戏。>>>>>

>上的游戏

我在这里说的是了解游戏规则所需的代码,然后可以评估情况和策略,以便在该游戏中击败您。复杂的东西。

为了说明,我要看一个我在一边开发的项目一段时间。 “小时”是指三年

,其中大多数是在理论上工作的高原上花费的,但太强烈了,无法使用……直到我想到了这种方法。该游戏是一个基于颜色和形状匹配的竞争难题。

>

JavaScript中的多线程

总结一下:您通过相邻的形状和颜色匹配来整个过程。例如,如果您开始使用绿色三角形 - 那么您可以移至任何其他三角形或任何其他绿色形状。您的目标是到达中间的水晶,然后将其带到板的另一侧,而对手则尝试这样做。您也可以从对手那里窃取水晶。

因此,我们有确定运动的逻辑规则,我们还可以看到策略的出现。例如,为了避免让对手到达水晶,或从您那里偷走它 - 您可能会选择阻止它们的动作,或者尝试在他们无法到达的地方完成。

计算机的工作是在任何给定的情况下找到最佳的动作,因此让我们查看摘要伪代码中的该过程:

>

for(var i=0; i<selectors.length i>
{ <br>
  if(base2.DOM.Document.matchAll <br>
    (contentdoc, selectors[i]).length > 0) <br>
  { <br>
    used ++; <br>
  } <br>
  else <br>
  { <br>
    unused ++; <br>
  } <br>
}</selectors.length>
我们评估了一种策略,如果这给了我们一个好的举动,那么我们就完成了;否则,我们将评估另一种策略,依此类推,直到我们有动作,或者得出结论,我们必须通过。

>每个策略功能都运行一个昂贵的过程,因为它必须评估董事会中的每个职位以及潜在的未来位置,可能会根据各种因素进行多次。该示例只有三种策略,但是在真实的游戏中,有数十种可能性,每个可能性都昂贵。

>

>单独评估中的任何一个都很好,但是所有这些评估都可以连续运行,使过度激烈的过程冻结了浏览器。

>

>因此,我所做的是将主代码拆分为“谨慎”任务

,每个任务都是用开关语句选择的,然后使用异步计时器进行迭代。这样做的逻辑距离那些小时候的那些选择您曾经有过的冒险书的逻辑不到一百万英里,在那里,每个任务都以实时的选择结束,直到我们到达终点:>

此代码比原始代码明显高得多,因此,如果减少代码大小是唯一的命令,这显然不是要走的路。

但是,我们在这里要做的是创建一个没有天花板的执行环境,即,在复杂性和长度方面没有上限的过程;这就是我们所做的。
function process() <br>
{ <br>
  var above = 0, below = 0; <br>
  for(var i=0; i
  { <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
  { <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>
}

这个模式可以无限期地扩展

,具有数百甚至数千个任务。它可能需要很长时间才能运行,但是将其运行,并且只要每个

个体

任务都不太强烈,它将在不杀死浏览器的情况下运行。>

无返回的路径 这种方法的强度也是它的主要弱点:由于内部函数是异步的,因此我们无法从外部函数中返回值。因此,例如,我们无法做到这一点(或者,我们可以,但没有意义):>

for(var i=0; i<selectors.length i>
{ <br>
  if(base2.DOM.Document.matchAll <br>
    (contentdoc, selectors[i]).length > 0) <br>
  { <br>
    used ++; <br>
  } <br>
  else <br>
  { <br>
    unused ++; <br>
  } <br>
}</selectors.length>

checksomething()函数将始终始终返回false,因为内部函数是异步的。外部功能将在内部功能的第一次迭代发生之前返回!

下一个示例同样毫无意义:

function process() <br>
{ <br>
  var above = 0, below = 0; <br>
  for(var i=0; i
  { <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
  { <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>
}

>我们不超出外部功能的范围,因此我们无法从中返回;该返回值无用地消失在以太中。

我们的> 在这里做的是从AJAX编码技术中取出叶子,并使用回调函数(在此示例中,我称为“ oncomplete”):

>


 

   
   
 


因此,当我们调用checkSomething()时,我们将匿名函数作为其参数,并且当作业完成时,该函数以最终值调用:

>
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项目。我开发了这种模式的游戏具有相当简单的逻辑,因此一个相当简单的brain>,但对于常规迭代而言,它仍然太多了。还有很多其他游戏需要更多的影响力!

>

我的下一个计划是使用此技术实现JavaScript国际象棋引擎。国际象棋具有各种可能的场景和战术,导致决策可能需要很长时间才能计算,远远超过没有这种技术的可行性。即使创建最基本的思维机器也需要进行激烈的计算,我承认对可能性感到非常兴奋。

>

如果我们能像这样删除技巧,谁能说出可能?自然语言处理,启发式方法……也许我们有在JavaScript中开发人工智能的基础!

>如果您喜欢阅读这篇文章,您会喜欢学习的;从大师那里学习新鲜技能和技术的地方。成员可以立即访问SitePoint的所有电子书和交互式在线课程,例如Web的JavaScript编程。 >对本文的评论已关闭。有关于JavaScript的疑问吗?为什么不在我们的论坛上询问? 图片来源:Randen l Peterson > Web工作人员在JavaScript多读力上的作用是什么?它们是Web内容在背景线程中运行脚本的简单手段。工作线程可以执行任务而不会干扰用户界面。此外,它们可以使用XMLHTTPRequest执行I/O(尽管响应XML和通道属性始终为null)。创建后,工人可以将消息发送到JavaScript代码,该消息通过将消息发布给该代码指定的事件处理程序(反之亦然)。 JavaScript如何处理多线程,尽管是单线读取?>

> javascript中多线程的限制是什么? 🎜>虽然可以通过Web Worker来实现JavaScript中的多线程,但重要的是要注意,这些工人无法访问DOM或其​​他Web API。它们仅限于几种可以来回发送到主线程的数据类型。另外,每个工人都是一个单独的实例,因此他们不共享范围或任何全局变量。

>为什么javascript支持多本身?

javascript被设计为避免复杂性和潜在的单线阅读数据操纵问题。多线程可能导致诸如种族条件之类的问题,其中输出取决于其他不可控制事件的序列或时间。据认为,优化单线读取环境会更容易,因为无需处理线程之间的依赖项。

>如何在JavaScript中使用Web Worker进行多线程?

>在JavaScript中使用Web Worker进行多线程,您需要创建一个新的Worker对象并指定在工作线程中执行要执行的JavaScript文件。然后,您可以使用tostmessage方法与工作线程进行通信,并使用onMessage事件处理程序从其接收消息。

>多插图可以使我的JavaScript代码更快?

多插图可能会使您的JavaScript代码可能使您的JavaScript代码。更快,但这取决于要执行的任务的性质。对于CPU密集型任务,多线程可以通过允许并行执行任务来显着提高性能。但是,对于I/O结合的任务,多线程的好处不太明显,因为这些任务通常受到CPU控制以外的因素的限制,例如网络速度。

>多线程和异步之间有什么区别在JavaScript?

>多线程和异步编程中的编程是否是同时管理多个任务的技术。但是,他们以不同的方式做到这一点。多线程涉及多个执行线程,每个线程执行不同的任务。另一方面,异步编程涉及单个执行线程,但是可以启动任务,然后暂停以稍后完成,从而允许在此期间执行其他任务。 JavaScript中的线程之间的数据共享?

> javaScript中线程之间的数据共享可以使用共享arraybuffer和Atomics实现。 sharedArrayBuffer允许在主线程和工作线程之间共享内存,而Atomics则提供了在共享内存上执行安全的原子操作的方法。

我可以在JavaScript中使用多线程进行前端开发吗? ,您可以在JavaScript中使用多线程进行前端开发。但是,重要的是要注意,启用多线程的Web工作人员无法访问DOM或其​​他Web API。因此,它们通常用于不涉及操纵DOM或与网页进行交互的任务,例如执行计算或处理数据。

以上是JavaScript中的多线程的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Python vs. JavaScript:您应该学到哪种语言?Python vs. JavaScript:您应该学到哪种语言?May 03, 2025 am 12:10 AM

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架:为现代网络开发提供动力JavaScript框架:为现代网络开发提供动力May 02, 2025 am 12:04 AM

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

JavaScript,C和浏览器之间的关系JavaScript,C和浏览器之间的关系May 01, 2025 am 12:06 AM

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

node.js流带打字稿node.js流带打字稿Apr 30, 2025 am 08:22 AM

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE

Python vs. JavaScript:性能和效率注意事项Python vs. JavaScript:性能和效率注意事项Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差异主要体现在:1)Python作为解释型语言,运行速度较慢,但开发效率高,适合快速原型开发;2)JavaScript在浏览器中受限于单线程,但在Node.js中可利用多线程和异步I/O提升性能,两者在实际项目中各有优势。

JavaScript的起源:探索其实施语言JavaScript的起源:探索其实施语言Apr 29, 2025 am 12:51 AM

JavaScript起源于1995年,由布兰登·艾克创造,实现语言为C语言。1.C语言为JavaScript提供了高性能和系统级编程能力。2.JavaScript的内存管理和性能优化依赖于C语言。3.C语言的跨平台特性帮助JavaScript在不同操作系统上高效运行。

幕后:什么语言能力JavaScript?幕后:什么语言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在浏览器和Node.js环境中运行,依赖JavaScript引擎解析和执行代码。1)解析阶段生成抽象语法树(AST);2)编译阶段将AST转换为字节码或机器码;3)执行阶段执行编译后的代码。

Python和JavaScript的未来:趋势和预测Python和JavaScript的未来:趋势和预测Apr 27, 2025 am 12:21 AM

Python和JavaScript的未来趋势包括:1.Python将巩固在科学计算和AI领域的地位,2.JavaScript将推动Web技术发展,3.跨平台开发将成为热门,4.性能优化将是重点。两者都将继续在各自领域扩展应用场景,并在性能上有更多突破。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),