Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Code-Erklärung der neuen HTML5-Multithreading-Funktion (Worker SharedWorker)

Detaillierte Code-Erklärung der neuen HTML5-Multithreading-Funktion (Worker SharedWorker)

黄舟
黄舟Original
2017-04-24 10:30:121788Durchsuche

Es besteht kein Zweifel, dass JavaScript nicht über Multithreading verfügt. Nachdem Sie eine Sache erledigt haben, führen Sie die nächste aus >Wenn es lange dauert, eine Sache zu tun, friert der Browser für eine Weile ein und reagiert nicht auf die Aktionen des Benutzers. Was sollen wir tun? Gott sei Dank bietet uns HTML5 einen Mechanismus zur Implementierung von Multithreading. Sie müssen so etwas Gutes schon vor langer Zeit verwendet haben, aber das spielt keine Rolle, lassen Sie es uns überprüfen zusammen! 1. Worker-Klasse

1. Methodeneinführung

(1)

Konstruktor

neu Worker(arg): Parameter Zeigt an die js-Datei, in der sich der von Ihrem Thread auszuführende Code befindet, z. B. „myworker.js“. Der Konstruktor gibt natürlich eine Instanz der Worker-Klasse zurück (2) worker.postMessage(message): Diese Methode gibt an, dass der Hauptthread eine Nachricht

an den Unterthread

sendet oder der Unterthread eine Nachricht an den Hauptthread sendet. Die Nachricht ist normalerweise eine Zeichenfolge oder eine js Objekt kann in ein Zeichen umgewandelt werden. Senden Sie es in Reihe (3) Es gibt auch eine Nachricht

Ereignis

für den Arbeiter, wenn jemand eine Nachricht an diesen sendet Worker-Instanz wird das Ereignis ausgelöst. Wir können den geposteten Wert aus dem -Attribut abrufen. Sie können sehen, dass die API

von Die Woker-Klasse ist recht einfach und enthält nur die beiden am häufigsten verwendeten Methoden und ein Ereignis. Nachfolgend sehen wir uns praktische Beispiele an.

Wenn ich „Big~Bear“ in das Textfeld eingebe und auf die Schaltfläche „Senden“
//main.html
<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>main</title></head><body>
    <p id="out"></p>
    <input type="text" name="" id="txt">
    <button id="btn">发送</button>
    <script type="text/javascript">
        var out = document.getElementById("out");        
        var btn = document.getElementById("btn");        
        var txt = document.getElementById("txt");        
        var worker = new Worker("thread1.js");
        btn.addEventListener("click",function(){            
        var postData = txt.value;
            worker.postMessage(postData);
        },false);
        worker.addEventListener(&#39;message&#39;,function(e){
            out.innerText = e.data;
        },false);    </script></body></html>
//thread1.js
onmessage = function(event){    
var res = event.data+"帅气!";
    postMessage(res);
}
klicke, erscheint der folgende Effekt

 

Einfache Analyse: Ich habe im Hauptthread eine Instanz von Worker von thead1.js erstellt. Wenn auf die Schaltfläche geklickt wird, wird die Methode postMessage aufgerufen, um den Inhalt im Textfeld an thread1.js zu senden thread1.js Wie? Das ist alles, wenn der Hauptthread eine Nachricht sendet, löst er dieses Ereignis aus und führt die Rückruffunktion

aus. Die Rückruffunktion ruft den vom Ereignisobjekt gesendeten Wert ab und fügt dann „ hinzu. Gutaussehend!" auf diesen Wert. , und dann zurückschicken. Der Hauptthread überwacht auch das Nachrichtenereignis des Arbeiters, sodass es ausgelöst wird, wenn eine Nachricht übergeben wird, und der Nachrichteninhalt in p angezeigt wird, sodass Sie den obigen Effekt sehen können.

Vielleicht kannst du das für etwas nutzen? Hier ist es wirklich sinnlos, den Vorgang des Hinzufügens von „handsome!“ im Hauptthread abzuschließen, da seine Komplexität O(1) ist (haha, ich lerne in letzter Zeit Algorithmen!), aber wenn dies nicht der Fall ist eine einfache Operation Wolltuch? Der Vorteil dieser Methode besteht darin, dass der Hauptthread nicht angehalten wird, egal wie kompliziert die Arbeit ist. Sobald der Unterthread die Daten verarbeitet hat kann es einfach übernehmen.

Lehrer Lu kann einen neuen Unterthread erstellen, indem er new Worker() im Unterthread aufruft. Ich habe festgestellt, dass dies nicht möglich ist und ein undefinierter Fehler gemeldet wird, was bedeutet, dass der Worker Das Konstrukt kann nicht im Unterthread aufgerufen werden. Ich dachte zuerst, ich hätte mich geirrt, aber später habe ich die offizielle Dokumentation überprüft und festgestellt, dass es keine relevante Beschreibung gab.

Schauen wir uns ein Beispiel für den Aufruf mehrerer Unterthreads im Hauptthread an:

//main.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>main</title>
</head>
<body>
    <div id="out"></div>
    <input type="text" name="" id="txt">
    <button id="btn">发送</button>
    <script type="text/javascript">

        var out = document.getElementById("out");
        var btn = document.getElementById("btn");
        var txt = document.getElementById("txt");
        var worker1 = new Worker("thread1.js");
        var worker2 = new Worker("thread2.js");
        btn.addEventListener("click",function(){
            var postData = txt.value;
            worker1.postMessage(postData);
        },false);
        worker1.addEventListener(&#39;message&#39;,function(e){
            worker2.postMessage(e.data);
            
        },false);
        worker2.addEventListener(&#39;message&#39;,function(e){
            out.innerText = e.data;
        },false);
    </script>
</body>
</html>
Der Hauptthread benötigt zwei Threads, um eine Aufgabe abzuschließen, und zwar Erstellen Sie zwei Threads, Worker1 und 2, fordern Sie zuerst Worker1 an, rufen Sie die zurückgegebenen Daten ab und fordern Sie dann Worker2 an. Gleichzeitig werden die von Worker1 verarbeiteten Daten zur Verarbeitung an w
//thread1.js
onmessage = function(event){    
var res = event.data+"帅气!";
        postMessage(res);    
}
ord
//thread2.js
onmessage = function(event){    
var res = event.data+"没骗你哟!";
    postMessage(res);
    close();
}
er2 übergeben und dann endgültig Das Ergebnis wird ermittelt und auf der Seite angezeigt.

Andere js-Dateien können in den untergeordneten Thread eingeführt und dann aufgerufen werden, wie im folgenden Beispiel.

//main.html
<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>main</title></head><body>
    <p id="out"></p>
    <input type="text" name="" id="txt">
    <button id="btn">发送</button>
    <script type="text/javascript">

        var out = document.getElementById("out");        
        var btn = document.getElementById("btn");        
        var txt = document.getElementById("txt");        
        var worker1 = new Worker("thread1.js");
        btn.addEventListener("click",function(){            
        var postData = txt.value;
            worker1.postMessage(postData);
        },false);
        worker1.addEventListener(&#39;message&#39;,function(e){
            out.innerText = e.data;
            
        },false);    </script></body></html>
Sie können sehen, dass unser thread1.js keine Datei namens tools.js hat, sondern eine js-Datei über importScripts() importiert, die Sie dann aufrufen können Weg, entlarvt zu werden.
//thread1.js
importScripts(&#39;tools.js&#39;)
onmessage = function(event){
    var res = handler(event.data);
        postMessage(res);    
}
//tools.js
function handler(data){
    return data+"加油加油!"
}
2. SharedWorker-Klasse

Das Wesentliche von SharedWorker ist das Teilen. Verschiedene Threads können einen Thread gemeinsam nutzen, und ihre Daten werden ebenfalls gemeinsam genutzt.

Lassen Sie es uns direkt anhand von Beispielen besprechen.

Verwendungsmethode eins:

Dies ist ein Beispiel aus
//main.html
<!DOCTYPE HTML><head>
    <title>Shared workers: demo 1</title></head><body>
    <p id="log"></p><script>
  var worker = new SharedWorker(&#39;shared.js&#39;);  
  var log = document.getElementById(&#39;log&#39;);
  worker.port.onmessage = function(e) { 
  // note: not worker.onmessage!    
  log.textContent += &#39;\n&#39; + e.data;
  }</script></body></html>
w3c
//shared.js

onconnect = function(e) {
  var port = e.ports[0];
  port.postMessage(&#39;Hello World!&#39;);
}
Schauen wir uns zuerst die zweite Methode an und analysieren sie dann

<!DOCTYPE HTML>
<html>
<head>
    <title>Shared workers: demo 2</title>
    </head>
    <body>
    <p id="log"></p>
    <script>
  var worker = new SharedWorker(&#39;shared.js&#39;);  
  var log = document.getElementById(&#39;log&#39;);
  worker.port.addEventListener(&#39;message&#39;, function(e) {
    log.textContent += &#39;\n&#39; + e.data;
  }, false);
  worker.port.start(); // note: need this when using addEventListener  
  worker.port.postMessage(&#39;ping&#39;);</script>
  </body></html>  
//shared
onconnect = function(e) {
  var port = e.ports[0];
  port.postMessage(&#39;Hello World!&#39;);
  port.onmessage = function(e) {
    port.postMessage(&#39;pong&#39;); // not e.ports[0].postMessage!
    // e.target.postMessage(&#39;pong&#39;); would work also
  }
}

  第一种方法中是使用事件句柄的方式将听message事件,不需要调用worker.port.start(),第二种方法是通过addEventListener()方法监听message事件,需要worker.port.start()方法激活端口。他们不同于worker,当有人和他通信时触发connect事件,然后他的message事件是绑定在messagePort对象上的,不想worker那样,你可以回头看看worker是怎么做的。

  那么sharedWorker是怎么共享数据的呢?请看下面的例子。

//main1 和main2都是这样
<!DOCTYPE HTML>
<html>
<head>
    <title>Shared workers: demo 2</title>
    </head>
    <body>
    <p id="log"></p>
    <input type="text" name="" id="txt">
    <button id="get">get</button>
    <button id="set">set</button>
    <script>
  var worker = new SharedWorker(&#39;shared.js&#39;);  
  var get = document.getElementById(&#39;get&#39;);  
  var set = document.getElementById(&#39;set&#39;);  
  var txt = document.getElementById(&#39;txt&#39;);  
  var log = document.getElementById(&#39;log&#39;);

  worker.port.addEventListener(&#39;message&#39;, function(e) {
    log.innerText = e.data;
  }, false);
  worker.port.start(); // note: need this when using addEventListener
  set.addEventListener(&#39;click&#39;,function(e){
      worker.port.postMessage(txt.value);
  },false);

  get.addEventListener(&#39;click&#39;,function(e){
      worker.port.postMessage(&#39;get&#39;);
  },false);</script></body></html>
//shared
var data;
onconnect = function(e) {
  var port = e.ports[0];
  port.onmessage = function(e) {
    
    if(e.data==&#39;get&#39;){
        port.postMessage(data);
    }else{
        data=e.data;
    }
  }
}

  这里分析一波,我们在main1.html的文本框输入数据,点击set,然后在main2.html中点击get法现能够获取到我们在main1.html中设置的数据,这说明我们的sharedWorker事实上是单例的,就像java中的static类一样,不管new多少个,实际上只有一个,这样我们的不同线程就可以共享到sharedWorker中的数据了。这里把图给上,记得有篇文章没给图,然后有人给我建议了,问能不能给图。

  

  最后来小结一下,worker和sharedWorker没有什么悬糊的,就是把台前的工作搬到幕后去做,不打断台前的工作。正所谓台上十分钟,台下十年功,如果你把台下的十年供放到台上做,观众的唾沫星子早就把你淹死了,所以说那些费事费力的工作还是放到台下去,台上只用展示你最好的一面的好了,十分钟足以! 

Das obige ist der detaillierte Inhalt vonDetaillierte Code-Erklärung der neuen HTML5-Multithreading-Funktion (Worker SharedWorker). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn