ก่อนที่ HTML5 JavaScript จะทำงานในเบราว์เซอร์ทำงานด้วยวิธีเดียว แม้ว่าจะมีหลายวิธีในการใช้การจำลองแบบหลายเธรด (เช่นวิธี setInterval, วิธีการตั้งถิ่นฐาน ฯลฯ ใน JavaScript) ในสาระสำคัญโปรแกรมการทำงานยังคงดำเนินการโดยเครื่องยนต์ JavaScript ในลักษณะเดียว เธรดคนงานที่แนะนำใน HTML5 เปิดใช้งานเอ็นจิ้น JavaScript ด้านเบราว์เซอร์เพื่อเรียกใช้งานรหัส JavaScript พร้อมกันดังนั้นจึงได้รับการสนับสนุนที่ดีสำหรับการเขียนโปรแกรมแบบมัลติเธรดด้านเบราว์เซอร์
มัลติเธรดใน JavaScript - Webworker ผู้ปฏิบัติงานบนเว็บใน HTML5 สามารถแบ่งออกเป็นสองประเภทที่แตกต่างกันหนึ่งประเภทหนึ่งคือคนงานเฉพาะเธรดเฉพาะและอีกประเภทหนึ่งคือพนักงานที่ใช้ร่วมกันที่ใช้ร่วมกัน เธรดสองประเภทมีการใช้งานที่แตกต่างกัน ผู้ปฏิบัติงานเว็บไซต์พิเศษคนงานเฉพาะเชื่อมต่อกับสคริปต์ที่สร้างขึ้น มันสามารถสื่อสารกับคนงานคนอื่น ๆ หรือส่วนประกอบเบราว์เซอร์ แต่ไม่สามารถสื่อสารกับ DOM ได้ ความหมายของเฉพาะคือเธรดนี้จะประมวลผลเพียงหนึ่งข้อกำหนดในแต่ละครั้ง เธรดเฉพาะจะถูกนำไปใช้ในเบราว์เซอร์กระแสหลักต่างๆยกเว้นเช่นและสามารถใช้งานได้อย่างมั่นใจ
สร้างเธรดการสร้างคนงานนั้นง่ายเพียงแค่ส่งชื่อไฟล์ของไฟล์ JavaScript ที่ต้องดำเนินการในเธรดไปยังตัวสร้าง
การสื่อสารเธรดการสื่อสารระหว่างเธรดหลักและเธรดลูกใช้วิธีการโพสต์และวิธีการ onmessage ของวัตถุเธรด ไม่ว่าใครจะส่งข้อมูลไปยังใครการส่งและการส่งใช้วิธีการโพสต์เมสเซจและตัวรับสัญญาณใช้วิธี onmessage เพื่อรับข้อมูล Postmessage มีพารามิเตอร์เดียวเท่านั้นนั่นคือข้อมูลที่ผ่านและ onMessage มีพารามิเตอร์เดียวเท่านั้น สมมติว่าเป็นเหตุการณ์ข้อมูลที่ได้รับผ่าน Event.data
ส่งข้อมูล JSONJSON เป็นสิ่งที่ JS สนับสนุน ไม่จำเป็นต้องใช้อะไรเลย เพียงใช้ข้อมูลที่ซับซ้อนใน JSON ตัวอย่างเช่น:
postmessage ({'cmd': 'init', 'timestamp': date.now ()});
การจัดการข้อผิดพลาดเมื่อเกิดข้อผิดพลาดในเธรดการโทรกลับเหตุการณ์ onerror จะถูกเรียก ดังนั้นวิธีการจัดการกับข้อผิดพลาดจึงง่ายมากซึ่งคือการติดตั้งเหตุการณ์ onerror ของอินสแตนซ์เธรด ฟังก์ชั่นการโทรกลับนี้มีข้อผิดพลาดพารามิเตอร์ซึ่งมี 3 ฟิลด์: ข้อความ - ข้อความแสดงข้อผิดพลาด; ชื่อไฟล์ - ไฟล์สคริปต์ที่เกิดข้อผิดพลาด Lineno - บรรทัดที่เกิดข้อผิดพลาด
ทำลายกระทู้ภายในเธรดใช้วิธีปิดเพื่อทำลายตัวเอง ในเธรดหลักด้านนอกเธรดวิธีการสิ้นสุดของอินสแตนซ์ของเธรดใช้เพื่อทำลายเธรด
ต่อไปนี้เป็นตัวอย่างที่จะดูการทำงานพื้นฐานของเธรด:
รหัส HTML:
<! doctype html>
<html>
<head>
<meta http-equiv = "content-type" content = "text /html; charset = utf-8" />
<tite> Web Worker Fibonacci </title>
<script type = "text/javascript">
onload = function () {
var worker = คนงานใหม่ ('fibonacci.js');
Worker.onMessage = ฟังก์ชั่น (เหตุการณ์) {
console.log ("ผลลัพธ์:" + event.data);
-
Worker.onerror = ฟังก์ชั่น (ข้อผิดพลาด) {
console.log ("ข้อผิดพลาด:" + error.message);
-
Worker.PostMessage (40);
-
</script>
</head>
<body>
</body>
</html>
ไฟล์สคริปต์ fibonacci.js รหัส:
//fibonacci.js
var fibonacci = function (n) {
กลับ n <2? n: arguments.callee (n - 1) + arguments.callee (n - 2);
-
onMessage = function (เหตุการณ์) {
var n = parseInt (event.data, 10);
postmessage (fibonacci (n));
-
วางไว้ในไดเรกทอรีเดียวกันเรียกใช้ไฟล์หน้าและดูคอนโซลเพื่อดูผลลัพธ์ของการรัน
มีอีกจุดหนึ่งที่นี่ ในหัวข้อหลักเหตุการณ์ onMessage สามารถติดยาเสพติดในอีกทางหนึ่ง:
Worker.addeventListener ('ข้อความ', ฟังก์ชั่น (เหตุการณ์) {
console.log ("ผลลัพธ์:" + event.data);
}, เท็จ);
โดยส่วนตัวแล้วฉันคิดว่ามันลำบากมากดังนั้นทำไมไม่ใช้ onmessage โดยตรง
ใช้ไฟล์สคริปต์อื่น ๆคนงานสามารถใช้การนำเข้าวิธีการทั่วโลกเพื่อโหลดและใช้ไฟล์สคริปต์ในโดเมนอื่น ๆ หรือไลบรารีคลาส ตัวอย่างเช่นต่อไปนี้เป็นวิธีการทางกฎหมายในการใช้:
importScripts ();/ * นำเข้าไม่มีอะไร */
importScripts ('foo.js'); / * นำเข้าเพียงแค่ "foo.js" */
importScripts ('foo.js', 'bar.js');/ * นำเข้าสองสคริปต์ */
หลังจากนำเข้าคุณสามารถใช้วิธีการในไฟล์เหล่านี้โดยตรง ดูตัวอย่างเล็ก ๆ ทางออนไลน์:
-
* ใช้เมธอด importScripts เพื่อแนะนำสคริปต์ทรัพยากรภายนอกที่นี่เราใช้เครื่องมือคำนวณสูตรทางคณิตศาสตร์ไลบรารี Math_Utilities.js
* เมื่อเอ็นจิ้น JavaScript โหลดไฟล์ทรัพยากรนี้ให้ดำเนินการต่อรหัสต่อไปนี้ต่อไป ในเวลาเดียวกันรหัสต่อไปนี้สามารถเข้าถึงและเรียกได้
* ตัวแปรและวิธีการที่กำหนดไว้ในไฟล์ทรัพยากร
-
importScripts ('math_utilities.js');
onMessage = ฟังก์ชั่น (เหตุการณ์)
-
var first = event.data.first;
var second = event.data.second;
คำนวณ (ครั้งแรก, วินาที);
-
ฟังก์ชั่นคำนวณ (ครั้งแรก, วินาที) {
// ทำงานการคำนวณ
var Common_divisor = ตัวหาร (แรก, วินาที);
var Common_multiple = หลาย (แรก, วินาที);
postmessage ("ทำงานเสร็จแล้ว!" +
"สิ่งที่พบได้น้อยที่สุดคือ" + Common_divisor +
"และตัวหารสามัญที่ยิ่งใหญ่ที่สุดคือ"+Common_multiple);
-
ชาวเน็ตบางคนบนอินเทอร์เน็ตก็คิดว่าจะใช้วิธีการนำเข้าที่นี่เพื่อแก้ปัญหาการโหลดทรัพยากรล่วงหน้า (เบราว์เซอร์โหลดทรัพยากรล่วงหน้าโดยไม่ต้องแยกวิเคราะห์และดำเนินการทรัพยากร) และเหตุผลก็ง่ายมาก
การทำรังด้ายในเธรดคนงานคุณยังสามารถสร้างเธรดเด็กและการดำเนินการต่าง ๆ ก็เหมือนกัน
ปัญหาการซิงโครไนซ์คนงานไม่มีกลไกการล็อคและปัญหาการซิงโครไนซ์แบบมัลติเธรดสามารถแก้ไขได้ด้วยรหัสเท่านั้น (เช่นการกำหนดตัวแปรสัญญาณ)
SharedWorker พนักงานเว็บที่ใช้ร่วมกันส่วนใหญ่เหมาะสำหรับปัญหาของการเชื่อมต่อหลายครั้งพร้อมกัน เนื่องจากจำเป็นต้องจัดการกับการเชื่อมต่อหลายครั้ง API ของมันแตกต่างจากคนงานเฉพาะเล็กน้อย นอกจากนี้ผู้ปฏิบัติงานบนเว็บที่ใช้ร่วมกันเช่นคนงานเฉพาะไม่สามารถเข้าถึง DOM และการเข้าถึงคุณสมบัติแบบฟอร์มก็ถูก จำกัด เช่นกัน พนักงานเว็บที่ใช้ร่วมกันไม่สามารถข้ามการสื่อสารได้เช่นกันอย่างไรก็ตามสคริปต์หน้าสามารถสื่อสารกับพนักงานเว็บที่ใช้ร่วมกันได้อย่างไรก็ตามแตกต่างจากผู้ปฏิบัติงานบนเว็บโดยเฉพาะเล็กน้อย (โดยใช้การสื่อสารพอร์ตโดยนัย) คือการสื่อสารนั้นดำเนินการอย่างชัดเจนโดยใช้วัตถุพอร์ตและแนบตัวจัดการเหตุการณ์ข้อความ
หลังจากได้รับข้อความแรกจากสคริปต์ Web Worker แล้ว Web Worker ที่ใช้ร่วมกันจะแนบตัวจัดการเหตุการณ์เข้ากับพอร์ตที่เปิดใช้งาน โดยทั่วไปตัวจัดการจะเรียกใช้เมธอด postmessage () ของตัวเองเพื่อส่งคืนข้อความไปยังรหัสการโทรจากนั้นวิธีการเริ่มต้นของพอร์ต () จะสร้างกระบวนการข้อความที่ถูกต้อง
ดูตัวอย่างเดียวที่คุณสามารถค้นหาได้บนอินเทอร์เน็ต: สร้างเธรดที่ใช้ร่วมกันเพื่อรับคำแนะนำที่ส่งจากการเชื่อมต่อที่แตกต่างกันจากนั้นใช้ตรรกะการประมวลผลคำสั่งของตัวเอง หลังจากการประมวลผลคำสั่งเสร็จสมบูรณ์ผลลัพธ์จะถูกส่งกลับไปยังผู้ใช้ที่เชื่อมต่อแต่ละราย
รหัส HTML:
<! doctype html>
<html>
<head>
<meta charset = "utf-8">
<title> ตัวอย่างผู้ปฏิบัติงานที่ใช้ร่วมกัน: วิธีการใช้งานที่ใช้ร่วมกันใน HTML5 </title>
<script>
var worker = new Sharedworker ('Sharedworker.js');
var log = document.getElementById ('response_from_worker');
Worker.port.addeventListener ('ข้อความ', ฟังก์ชั่น (e) {
// บันทึกข้อมูลการตอบกลับในหน้าเว็บ
log.textContent = e.data;
}, เท็จ);
Worker.port.start ();
Worker.port.postMessage ('ping จากหน้าเว็บผู้ใช้ .. ');
// วิธีการต่อไปนี้จะส่งอินพุตผู้ใช้ไปยัง SharedWorker
ฟังก์ชั่น postmessagetosharedworker (อินพุต)
-
// กำหนดวัตถุ JSON เพื่อสร้างคำขอ
คำสั่ง var = {คำสั่ง: input.value};
Worker.port.postMessage (คำแนะนำ);
-
</script>
</head>
<body onload = ''>
<output id = 'response_from_worker'>
ตัวอย่างผู้ปฏิบัติงานที่ใช้ร่วมกัน: วิธีการใช้งานที่ใช้ร่วมกันใน HTML5
</utput>
ส่งคำแนะนำไปยังคนงานที่ใช้ร่วมกัน:
<อินพุต type = "text" autofocus oninput = "postmessagetosharedworker (this); return false;">
</prong>
</body>
</html>
รหัสไฟล์สคริปต์:
// สร้างเธรดที่ใช้ร่วมกันเพื่อรับคำแนะนำที่ส่งจากการเชื่อมต่อที่แตกต่างกัน หลังจากการประมวลผลคำสั่งเสร็จสมบูรณ์ผลลัพธ์จะถูกส่งกลับไปยังผู้ใช้ที่เชื่อมต่อแต่ละราย
var connect_number = 0;
onConnect = function (e) {
connect_number = connect_number+ 1;
// รับพอร์ตแรกที่นี่
var port = e.ports [0];
port.postMessage ('การเชื่อมต่อใหม่! หมายเลขการเชื่อมต่อปัจจุบันคือ'
+ connect_number);
port.onMessage = function (e) {
// รับคำแนะนำจากผู้ร้องขอ
คำสั่ง var = e.data.instruction;
ผลลัพธ์ var = execute_instruction (คำสั่ง);
port.postMessage ('คำขอ:'+คำสั่ง+'การตอบกลับ'+ผลลัพธ์
+'จากคนงานที่ใช้ร่วมกัน ... ');
-
-
-
* ฟังก์ชั่นนี้จะถูกใช้เพื่อดำเนินการตามคำแนะนำที่ส่งจากผู้ร้องขอ
* คำสั่ง @param
* @กลับ
-
ฟังก์ชั่น execute_instruction (คำสั่ง)
-
var result_value;
// ใช้ตรรกะของคุณที่นี่
// ดำเนินการตามคำสั่ง ...
return result_value;
-
ในตัวอย่างเธรดที่ใช้ร่วมกันข้างต้นวัตถุเธรดที่ใช้ร่วมกันถูกสร้างขึ้นในหน้าหลักนั่นคือหน้าการเชื่อมต่อผู้ใช้แต่ละหน้าและวิธีการถูกกำหนดเพื่อส่งคำแนะนำผู้ใช้ที่เข้ามาไปยังเธรดที่ใช้ร่วมกัน ในเวลาเดียวกัน Connect_Number ถูกกำหนดไว้ในตัวอย่างรหัสการใช้งานของเธรดที่ใช้ร่วมกันเพื่อบันทึกจำนวนทั้งหมดที่เชื่อมต่อกับเธรดที่ใช้ร่วมกัน หลังจากนั้นให้ใช้โปรเซสเซอร์เหตุการณ์ OnConnect เพื่อรับการเชื่อมต่อจากผู้ใช้ที่แตกต่างกันและแยกวิเคราะห์คำแนะนำที่พวกเขาผ่าน ในที่สุดวิธีการดำเนินการ _instruction ถูกกำหนดเพื่อดำเนินการตามคำแนะนำของผู้ใช้ หลังจากการดำเนินการคำสั่งเสร็จสมบูรณ์ผลลัพธ์จะถูกส่งกลับไปยังผู้ใช้แต่ละคน
ที่นี่เราไม่ได้ใช้ตัวจัดการเหตุการณ์ onMessage ของเธรดคนงานเช่นตัวอย่างก่อนหน้า แต่ใช้วิธีอื่นในการ AddEventListener ในความเป็นจริงดังที่ได้กล่าวไว้ก่อนหน้านี้หลักการดำเนินการของทั้งสองนี้นั้นเหมือนกัน แต่มีความแตกต่างเล็กน้อยที่นี่ หากคุณใช้ AddEventListener เพื่อรับข้อความจากเธรดที่ใช้ร่วมกันคุณต้องใช้เมธอดผู้ทำงาน Port.start () ก่อนเพื่อเริ่มต้นพอร์ตนี้ หลังจากนั้นคุณสามารถรับและส่งข้อความได้ตามปกติเช่นเดียวกับวิธีการใช้เธรดคนงาน
คำสั่งสุดท้าย สิ่งที่คุณสามารถทำได้ในเธรด :1. สามารถใช้ settimeout (), cleartimeout (), setInterval (), clearInterval () และฟังก์ชั่นอื่น ๆ
2. สามารถใช้วัตถุ Navigator
3. สามารถใช้ xmlhttprequest เพื่อส่งคำขอ
4. คุณสามารถใช้ที่เก็บข้อมูลเว็บในเธรด
5. คุณสามารถใช้ตัวเองเพื่อรับขอบเขตของเธรดนี้ในเธรด
สิ่งที่ไม่สามารถทำได้ในเธรด :1. วัตถุ DOM/BOM นอกเหนือจาก Navigator ไม่สามารถใช้ในเธรดเช่นหน้าต่างและเอกสาร (หากคุณต้องการใช้งานคุณสามารถส่งข้อความไปยังผู้สร้างคนงานและดำเนินการผ่านฟังก์ชั่นการโทรกลับ)
2. ตัวแปรและฟังก์ชั่นในเธรดหลักไม่สามารถใช้ในเธรดได้
3. คำสั่งการดำเนินการที่มีเอฟเฟกต์ระงับไม่สามารถใช้ในเธรดเช่นการแจ้งเตือน ฯลฯ
4. JS ไม่สามารถโหลดผ่านโดเมนในเธรดได้
เธรดยังต้องการการใช้ทรัพยากรและการใช้เธรดจะนำมาซึ่งความซับซ้อนบางอย่างดังนั้นหากไม่มีเหตุผลเพียงพอที่จะใช้เธรดเพิ่มเติมอย่าใช้
การอ้างอิงเชิงปฏิบัติเอกสารอย่างเป็นทางการ: http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html
คำอธิบายการจำแนกประเภทผู้ไปพบเว็บ: http://www.w3schools.com/html5/html5_workers.asp
ความกังวลเทมเพลต: http://www.cuoxin.com/w3school/html5/
ภาพรวม webworker: https://developer.mozilla.org/en/using_web_workers