เมื่อพูดถึง HTML5 ผู้คนมักจะพูดถึงมันอยู่เสมอ มีฟีเจอร์มากมายและ API ที่น่าสนใจที่กำลังรีเฟรช อย่างไรก็ตาม รองเท้าสำหรับเด็กจำนวนมากยังคงอยู่ในขั้นความหมายและไม่สนใจพลังของ HTML5
ในส่วนนี้เราจะพูดถึง Web-Worker แบบมัลติเธรด
1. ทำให้ชัดเจนว่า JavaScript เป็นแบบเธรดเดียวคุณสมบัติที่สำคัญของภาษา JavaScript ก็คือ เป็นแบบเธรดเดียว ซึ่งหมายความว่าสามารถทำได้ทีละอย่างเท่านั้น
มันฟังดูแปลก ทำไมไม่ออกแบบมันด้วยมัลติเธรดเพื่อปรับปรุงประสิทธิภาพล่ะ? เราสามารถสมมติสถานการณ์ได้:
สมมติว่า JavaScript
มีสองเธรดในเวลาเดียวกัน เธรดหนึ่งเพิ่มเนื้อหาให้กับโหนด DOM
บางตัว และเธรดอื่นลบโหนดในกรณีนี้ เธรดใดที่เบราว์เซอร์ควรใช้
ในฐานะภาษาสคริปต์ของเบราว์เซอร์ วัตถุประสงค์หลักของ JavaScript
คือการโต้ตอบกับผู้ใช้และจัดการ DOM
สิ่งนี้กำหนดว่าสามารถเป็นแบบเธรดเดียวเท่านั้น มิฉะนั้นจะทำให้เกิดปัญหาการซิงโครไนซ์ที่ซับซ้อนมาก เพื่อหลีกเลี่ยงความซับซ้อน JavaScript
จึงเป็นแบบเธรดเดียวตั้งแต่แรกเกิด นี่เป็นคุณลักษณะหลักของภาษาและคาดว่าจะเปลี่ยนแปลงได้ยากในระยะสั้น
เธรดเดี่ยวถือเป็นจุดที่ยุ่งยากมาโดยตลอด เพื่อใช้ประโยชน์จากพลังการประมวลผลของ CPU
แบบมัลติคอร์ HTML5
จึงเสนอมาตรฐาน Web Worker
ซึ่งอนุญาตให้สคริปต์ JavaScript
สร้างหลายเธรดได้ อย่างไรก็ตาม เธรดลูกจะถูกควบคุมโดยเธรดหลักอย่างสมบูรณ์ และต้องไม่ดำเนินการ DOM
ดังนั้น มาตรฐานใหม่นี้จึงไม่เปลี่ยนแปลงลักษณะเธรดเดี่ยวของ JavaScript
Web Workers
เป็นโซลูชันมัลติเธรด JavaScript
ที่ให้บริการโดยเบราว์เซอร์สมัยใหม่ เราสามารถพบสถานการณ์การใช้งานได้มากมาย:
1. เราสามารถใช้ Web Worker
เพื่อดำเนินการบางอย่างที่ต้องใช้การคำนวณสูง
2. สามารถดำเนินการสำรวจได้และบางรัฐสามารถเปลี่ยนแปลงได้
3. การอัพเดตสถานะข้อความส่วนหัว เช่น การแจ้งจำนวนข้อความในส่วนหัวของหน้า
4. การโต้ตอบของผู้ใช้ความถี่สูง การตรวจสอบการสะกด เช่น การช่วยเหลือผู้ใช้ในการแก้ไขข้อผิดพลาดในการป้อนข้อมูลและฟังก์ชันแก้ไขตามพฤติกรรมการป้อนข้อมูลของผู้ใช้ บันทึกประวัติ แคช และข้อมูลอื่น ๆ
5. การเข้ารหัส: บางครั้งการเข้ารหัสอาจใช้เวลานานมาก โดยเฉพาะอย่างยิ่งหากคุณต้องการเข้ารหัสข้อมูลจำนวนมากบ่อยครั้ง (เช่น การเข้ารหัสข้อมูลก่อนส่งไปยังเซิร์ฟเวอร์)
6. ดึงข้อมูลล่วงหน้า: เพื่อเพิ่มประสิทธิภาพเว็บไซต์หรือเว็บแอปพลิเคชันของคุณและปรับปรุงเวลาในการโหลดข้อมูล คุณสามารถใช้ Workers
เพื่อโหลดข้อมูลบางส่วนไว้ล่วงหน้าในกรณีที่คุณต้องการ
การเข้ารหัสเป็นสถานการณ์ที่ยอดเยี่ยมสำหรับการใช้งาน Web Worker
เนื่องจากไม่จำเป็นต้องเข้าถึง DOM
หรือเวทย์มนตร์อื่นๆ เพียงแต่ใช้อัลกอริธึมในการคำนวณเท่านั้น เนื่องจากสาธารณชนให้ความสนใจกับข้อมูลส่วนบุคคลที่ละเอียดอ่อนมากขึ้น ความปลอดภัยของข้อมูลและการเข้ารหัสจึงกลายเป็นเรื่องสำคัญที่สุด สิ่งนี้สะท้อนให้เห็นได้จากเหตุการณ์การรั่วไหลของข้อมูลผู้ใช้ 12306 ล่าสุด
เมื่อดำเนินการคำนวณใน Worker แล้ว ผู้ใช้จะราบรื่นและไม่ส่งผลกระทบต่อประสบการณ์ผู้ใช้
3. ความเข้ากันได้ 4. แนวคิดพื้นฐาน1. ก่อนอื่นอย่าลืมตัดสินว่ารองรับหรือไม่
ถ้า (window.Worker) { ... }
2. การสร้าง worker
ใหม่เป็นเรื่องง่าย
const myWorker = ผู้ปฏิบัติงานใหม่ ('worker.js');
เมธอด postMessage() และตัวจัดการเหตุการณ์ onmessage ถือเป็นมนต์ดำของ Workers
3. postMessage
ใช้เพื่อส่งข้อความ และ onmessage
ใช้เพื่อฟังข้อความ
const worker = new Worker('src/worker.js');worker.onmessage = e => { console.log(e.data);};worker.postMessage('สบายดีไหม!');
เมื่อใช้ในเธรดหลัก onmessage
และ postMessage()
จะต้องถูกแขวนไว้บนวัตถุ worker
แต่ไม่จำเป็นเมื่อใช้ใน worker
เหตุผลก็คือ ภายใน worker
นั้น worker
ถือเป็นขอบเขตระดับโลกอย่างมีประสิทธิผล
4.การจัดการข้อยกเว้น:
worker.onerror = ฟังก์ชั่น (ข้อผิดพลาด) { console.log (error.message); ข้อผิดพลาดในการโยน;};
5. เลิก worker
ผู้ปฏิบัติงานยุติ ();
เธรด worker
จะถูกปิดทันที โดยไม่มีโอกาสดำเนินการหรือล้างข้อมูลให้เสร็จสิ้น
6. ในเธรด worker
workers
ยังสามารถเรียกวิธี close
ของตนเองเพื่อปิด:
ปิด();5. เริ่มต้นอย่างรวดเร็ว
เพื่อให้เข้าใจได้อย่างรวดเร็ว เรามายกตัวอย่างเล็กๆ น้อยๆ กัน โครงสร้างโครงการมีดังนี้
├── index.html└── src ├── main.js └── worker.js
HTML
<html><head> <title>การสาธิตการทำงานของเว็บ</title> <meta charset=UTF-8 /></head><body> <div id=app> สวัสดี Jartto! </div> <script src=src /main.js></script></body></html>
main.js
const worker = new Worker('src/worker.js');worker.onmessage = e => { const message = e.data; console.log(`[จาก Worker]: ${message}`); ('app').innerHTML = message;};worker.postMessage('เขียนได้ดี!');
เวิร์ค.เจส
onmessage = e => { const message = e.data; console.log(`[จากหลัก]: ${message}`); if(message.indexOf('Good') > -1) { postMessage('Thank you สำหรับการสนับสนุนของคุณ '); }};
รหัสนั้นง่ายมาก เธรดหลักส่ง: "มันเขียนได้ดีมาก!"
เจ้าหน้าที่เว็บได้รับข้อความและพบว่าเนื้อหามีคำว่า "ดี" จึงส่งกลับไปที่กระทู้หลัก: "ขอบคุณสำหรับการสนับสนุน"
6. ข้อจำกัด 1. ภายใน worker
คุณไม่สามารถใช้งานโหนด DOM
ได้โดยตรง และคุณไม่สามารถใช้วิธีการและคุณสมบัติเริ่มต้นของวัตถุ window
ได้ อย่างไรก็ตาม เราสามารถใช้สิ่งต่างๆ มากมายภายใต้วัตถุ window
รวมถึงกลไกการจัดเก็บข้อมูล เช่น WebSockets
, IndexedDB
และ Data Store API
เฉพาะ FireFox OS
นี่คือตัวอย่างที่เราแก้ไข main.js
:
const worker = new Worker('src/worker.js');worker.onmessage = e => { const message = e.data; console.log(`[จาก Worker]: ${message}`); ('แอป').innerHTML = ข้อความ;};+ worker.onerror = ฟังก์ชั่น (ข้อผิดพลาด) {+ console.log (ข้อผิดพลาด);+ worker.terminate();+ };worker.postMessage('เขียนได้ดี!');
มาแก้ไข work.js
อีกครั้ง
+ alert('jartto');onmessage = e => { const message = e.data; console.log(`[จากหลัก]: ${message}`); if(message.indexOf('good') > - 1) { postMessage('ขอบคุณสำหรับการสนับสนุน' }};
ในเวลานี้ การวิ่งจะรายงาน:
เนื่องจาก: บริบทที่ดำเนินการ worker.js
แตกต่างจากบริบทที่ดำเนินการ HTML
ของหน้าหลัก ออบเจ็กต์ระดับบนสุดไม่ใช่ Window
ซึ่งเป็นบริบทส่วนกลางสำหรับการดำเนินการ woker.js
แต่เป็น WorkerGlobalScope
ให้เราอธิบายรายละเอียด
2. การถ่ายโอนข้อมูลระหว่าง workers
และเธรดหลักดำเนินการผ่านกลไกข้อความดังกล่าว: ทั้งสองฝ่ายใช้วิธี postMessage()
เพื่อส่งข้อความของตนเอง และใช้ตัวจัดการเหตุการณ์ onmessage
เพื่อตอบสนองต่อข้อความ (ข้อความรวมอยู่ใน คุณลักษณะ data
ของเหตุการณ์ Message
)
ในกระบวนการนี้ ข้อมูลจะไม่ถูกแชร์แต่จะถูกคัดลอก
3. ข้อจำกัดแหล่งกำเนิดเดียวกัน
ไฟล์สคริปต์ที่กำหนดให้กับเธรด Worker
จะต้องมีต้นกำเนิดเดียวกันกับไฟล์สคริปต์ของเธรดหลัก
4. ข้อจำกัดของไฟล์
เธรด Worker
ไม่สามารถอ่านไฟล์ในเครื่องได้ กล่าวคือ ไม่สามารถเปิดระบบไฟล์ในเครื่องได้ (file://)
สคริปต์ที่โหลดจะต้องมาจากเซิร์ฟเวอร์
5. ไม่อนุญาตให้ใช้ไฟล์ในเครื่อง
Uncaught SecurityError: ไม่สามารถสร้างผู้ปฏิบัติงานได้:
สคริปต์ที่ '(path)/worker.js'
ไม่สามารถเข้าถึงได้จากจุดเริ่มต้น 'null'
Chrome ไม่อนุญาตให้คุณโหลดพนักงานเว็บเมื่อเรียกใช้สคริปต์จากไฟล์ในเครื่อง
แล้วจะแก้ยังไงล่ะ? เราสามารถเริ่มต้นเซิร์ฟเวอร์ท้องถิ่นได้ แนะนำให้ใช้ http-server
ซึ่งง่ายและใช้งานง่าย
6. นโยบายการรักษาความปลอดภัยของเนื้อหา
worker
มีบริบทการดำเนินการของตนเอง แตกต่างจากออบเจ็กต์ document
ที่สร้างขึ้น โดยทั่วไปแล้ว worker
ไม่ได้ถูกจำกัดโดยนโยบายความปลอดภัยของเนื้อหาของ document
(หรือ worker
หลัก ) ที่สร้างเอกสารนั้น
ลองมาตัวอย่าง สมมติว่า document
มีการประกาศส่วนหัวต่อไปนี้:
นโยบายความปลอดภัยเนื้อหา: script-src 'self'
วัตถุประสงค์ส่วนหนึ่งของการประกาศนี้คือเพื่อห้ามไม่ให้โค้ดสคริปต์ที่อยู่ภายในนั้นใช้เมธอด eval()
อย่างไรก็ตาม หากโค้ดสคริปต์สร้าง worker
โค้ดที่ดำเนินการในบริบทของ worker
จะสามารถใช้ eval()
ได้
ในการระบุ CSP สำหรับผู้ปฏิบัติงาน คำขอส่งรหัสผู้ปฏิบัติงานจะต้องต่อท้ายด้วย CSP
ข้อยกเว้นประการหนึ่งคือ หากแหล่งที่มาของสคริปต์ worker
เป็นตัวระบุที่ไม่ซ้ำกันทั่วโลก (เช่น URL
ระบุสคีมาข้อมูลหรือ blob
) worker
จะสืบทอด document
หรือ CSP
worker
ที่สร้างขึ้น
เกี่ยวกับ เราสามารถค้นหาเอกสารเกี่ยวกับ MDN
:
1. self
:
เราสามารถใช้คุณสมบัติ self
ของ WorkerGlobalScope
เพื่อรับการอ้างอิงถึงวัตถุนั้นเอง
2. location
:
แอ็ตทริบิวต์ location
ส่งคืน WorkerLocation
ที่เชื่อมโยงกับเธรดเมื่อถูก URL
ขึ้น โดยแสดงถึง URL
ที่สมบูรณ์ของทรัพยากรสคริปต์ที่ใช้ในการเริ่มต้นเธรดของผู้ปฏิบัติงาน จะไม่เปลี่ยนแปลง แม้ว่าเพจจะถูกเปลี่ยนเส้นทางหลายครั้งก็ตาม
3. close
:
ปิดเธรดปัจจุบัน คล้ายกับ terminate
4. caches
:
บริบทปัจจุบันมี CacheStorage
เพื่อให้แน่ใจว่ามีความพร้อมใช้งานแบบออฟไลน์และสามารถปรับแต่งการตอบสนองต่อคำขอได้
5. console
:
สนับสนุน console
6. importScripts
เราสามารถโหลดฟังก์ชันไลบรารีใน worker
ผ่าน url
ผ่านเมธอด importScripts()
7. XMLHttpRequest
ด้วยเหตุนี้จึงสามารถส่งคำขอ Ajax
ได้
8. คุณสามารถใช้:
มี API
มากมายที่สามารถใช้ได้ ดังนั้นฉันจะไม่ยกตัวอย่างทีละรายการที่นี่
เมื่อ worker
พบข้อผิดพลาดที่ทำงานอยู่ ตัวจัดการเหตุการณ์ onerror
จะถูกเรียก จะได้รับเหตุการณ์ชื่อ error
ที่ขยายอินเทอร์เฟซ ErrorEvent
กิจกรรมไม่เกิดฟองสบู่และสามารถยกเลิกได้
เพื่อป้องกันไม่ให้การดำเนินการเริ่มต้นถูกทริกเกอร์ ผู้ปฏิบัติงานสามารถเรียกใช้เมธอด PreventDefault() ของเหตุการณ์ข้อผิดพลาดได้
โดยทั่วไปเราใช้ข้อมูลสำคัญสามส่วนต่อไปนี้สำหรับเหตุการณ์ข้อผิดพลาด:
worker.onerror = function (ข้อผิดพลาด) { console.log (error.message); ข้อผิดพลาดในการโยน;};
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network