目錄
“太激烈”多麼激烈?
android shove silicon綿羊的夢想?
>如何在JavaScript中使用Web Worker進行多線程?
>多插圖可以使我的JavaScript代碼更快?
首頁 web前端 js教程 JavaScript中的多線程

JavaScript中的多線程

Feb 25, 2025 am 11:37 AM

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>
{ <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>
}
登入後複製
登入後複製
登入後複製
如果我們允許它繼續下去,在另外90個迭代後,Firefox再次產生相同的對話框。在這方面,Safari 3和Internet Explorer 6的行為類似,並具有凍結的UI和一個警告對話框的閾值。在Opera中沒有這樣的對話框 - 它只是繼續運行代碼直到完成代碼 - 但是瀏覽器UI類似地凍結了直到完成任務。

顯然,在實踐中我們無法運行代碼。因此,讓我們重新開始並使用異步計時器進行外循環:>

>現在讓我們再次運行……這一次我們會收到完全不同的結果。該代碼需要一段時間才能完成,但是它可以一直成功地運行到末端,而沒有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推到從未被設計為去的所有這些地方?您的代碼太強烈了。這是工作的錯誤工具。如果您必須跳過這類箍,那麼您的應用程序的設計從根本上是錯誤的。

>我已經提到了一個例子,我必須找到一種繁重的腳本工作的方法。就是這樣,或者整個想法必須放棄。如果您不相信該答案,那麼本文的其餘部分也可能對您不吸引您。

>但是,如果您是 - 或者至少,如果您願意說服它,這是另一個真正可以將其釘在家裡的示例:使用JavaScript編寫可以在計算機上進行比賽的遊戲。 >>>>>

>上的遊戲

我在這裡說的是了解遊戲規則所需的代碼,然後可以評估情況和策略,以便在該遊戲中擊敗您。複雜的東西。

為了說明,我要看一個我在一邊開發的項目一段時間。 “小時”是指三年

,其中大多數是在理論上工作的高原上花費的,但太強烈了,無法使用……直到我想到了這種方法。該遊戲是一個基於顏色和形狀匹配的競爭難題。

>

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>
}
登入後複製
登入後複製
登入後複製

這個模式可以無限期地擴展

,具有數百甚至數千個任務。它可能需要很長時間才能運行,但是將其運行,並且只要每個

個體

任務都不太強烈,它將在不殺死瀏覽器的情況下運行。 >

無返回的路徑 這種方法的強度也是它的主要弱點:由於內部函數是異步的,因此我們無法從外部函數中返回值。因此,例如,我們無法做到這一點(或者,我們可以,但沒有意義):>

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>
}
登入後複製
登入後複製
登入後複製
登入後複製

checksomething()函數將始終始終返回false,因為內部函數是異步的。外部功能將在內部功能的第一次迭代發生之前返回!

下一個示例同樣毫無意義:

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>
}
登入後複製
登入後複製
登入後複製

>我們不超出外部功能的範圍,因此我們無法從中返回;該返回值無用地消失在以太中。

我們的> 在這裡做的是從AJAX編碼技術中取出葉子,並使用回調函數(在此示例中,我稱為“ oncomplete”):

>
<form action=""> <br>
  <fieldset> <br>
    <input type="button" value="test1" onclick="test1()" /> <br>
    <input type="text"  /> <br>
  </fieldset> <br>
</form> <br>
登入後複製

因此,當我們調用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

熱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漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1655
14
CakePHP 教程
1414
52
Laravel 教程
1307
25
PHP教程
1255
29
C# 教程
1228
24
神秘的JavaScript:它的作用以及為什麼重要 神秘的JavaScript:它的作用以及為什麼重要 Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的演變:當前的趨勢和未來前景 JavaScript的演變:當前的趨勢和未來前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript引擎:比較實施 JavaScript引擎:比較實施 Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript:探索網絡語言的多功能性 JavaScript:探索網絡語言的多功能性 Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

如何使用Next.js(前端集成)構建多租戶SaaS應用程序 如何使用Next.js(前端集成)構建多租戶SaaS應用程序 Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

從C/C到JavaScript:所有工作方式 從C/C到JavaScript:所有工作方式 Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

如何安裝JavaScript? 如何安裝JavaScript? Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

See all articles