HTML5 - Web Workers

JavaScript ได้รับการออกแบบให้ทำงานในสภาพแวดล้อมแบบเธรดเดียวซึ่งหมายความว่าสคริปต์หลายตัวไม่สามารถทำงานในเวลาเดียวกันได้ พิจารณาสถานการณ์ที่คุณต้องจัดการกับเหตุการณ์ UI สืบค้นและประมวลผลข้อมูล API จำนวนมากและจัดการ DOM

JavaScript จะหยุดเบราว์เซอร์ของคุณในสถานการณ์ที่การใช้งาน CPU สูง ให้เรายกตัวอย่างง่ายๆที่ JavaScript ผ่านลูปใหญ่ -

<!DOCTYPE HTML>

<html>
   <head>
      <title>Big for loop</title>
      
      <script>
         function bigLoop() {
            
            for (var i = 0; i <= 10000; i += 1) {
               var j = i;
            }
            alert("Completed " + j + "iterations" );
         }
         
         function sayHello(){
            alert("Hello sir...." );
         }
      </script>
      
   </head>
   
   <body>
      <input type = "button" onclick = "bigLoop();" value = "Big Loop" />
      <input type = "button" onclick = "sayHello();" value = "Say Hello" />
   </body>
</html>

มันจะให้ผลลัพธ์ดังต่อไปนี้ -

เมื่อคุณคลิกปุ่ม Big Loop จะแสดงผลลัพธ์ต่อไปนี้ใน Firefox -

Web Workers คืออะไร?

สถานการณ์ที่อธิบายข้างต้นสามารถจัดการได้โดยใช้ Web Workers ใครจะทำงานที่มีราคาแพงในการคำนวณทั้งหมดโดยไม่ขัดจังหวะส่วนต่อประสานผู้ใช้และโดยทั่วไปจะทำงานบนเธรดแยกกัน

Web Workers อนุญาตให้ใช้สคริปต์ที่ทำงานเป็นเวลานานซึ่งไม่ถูกขัดจังหวะโดยสคริปต์ที่ตอบสนองต่อการคลิกหรือการโต้ตอบกับผู้ใช้อื่น ๆ และอนุญาตให้ดำเนินการงานที่ยาวนานโดยไม่ต้องยอมเพื่อให้เพจตอบสนอง

Web Workers เป็นสคริปต์พื้นหลังและมีน้ำหนักค่อนข้างมากและไม่ได้ตั้งใจให้ใช้เป็นจำนวนมาก ตัวอย่างเช่นการเปิดตัวคนงานหนึ่งคนสำหรับแต่ละพิกเซลของภาพสี่เมกะพิกเซลนั้นไม่เหมาะสม

เมื่อสคริปต์ทำงานภายใน Web Worker จะไม่สามารถเข้าถึงอ็อบเจ็กต์หน้าต่างของเว็บเพจ (window.document) ซึ่งหมายความว่า Web Workers ไม่มีสิทธิ์เข้าถึงเว็บเพจและ DOM API โดยตรง แม้ว่า Web Workers จะไม่สามารถบล็อก UI ของเบราว์เซอร์ได้ แต่ก็ยังสามารถใช้รอบ CPU และทำให้ระบบตอบสนองน้อยลง

Web Workers ทำงานอย่างไร?

Web Workers เริ่มต้นด้วย URL ของไฟล์ JavaScript ซึ่งมีรหัสที่ผู้ปฏิบัติงานจะเรียกใช้ รหัสนี้ตั้งค่าผู้ฟังเหตุการณ์และสื่อสารกับสคริปต์ที่สร้างจากหน้าหลัก ต่อไปนี้เป็นไวยากรณ์อย่างง่าย -

var worker = new Worker('bigLoop.js');

หากมีไฟล์ javascript ที่ระบุเบราว์เซอร์จะสร้างเธรดผู้ปฏิบัติงานใหม่ซึ่งดาวน์โหลดแบบอะซิงโครนัส หากเส้นทางไปยังผู้ปฏิบัติงานของคุณส่งกลับข้อผิดพลาด 404 ผู้ปฏิบัติงานจะล้มเหลวโดยไม่โต้ตอบ

หากแอปพลิเคชันของคุณมีไฟล์ JavaScript ที่รองรับหลายไฟล์คุณสามารถนำเข้าได้ importScripts() วิธีการที่ใช้ชื่อไฟล์เป็นอาร์กิวเมนต์โดยคั่นด้วยลูกน้ำดังนี้ -

importScripts("helper.js", "anotherHelper.js");

เมื่อสร้าง Web Worker แล้วการสื่อสารระหว่าง Web Worker และเพจพาเรนต์จะทำได้โดยใช้ไฟล์ postMessage()วิธี. ขึ้นอยู่กับเบราว์เซอร์ / เวอร์ชันของคุณ postMessage () สามารถยอมรับสตริงหรือออบเจ็กต์ JSON เป็นอาร์กิวเมนต์เดียว

ข้อความที่ส่งผ่านโดย Web Worker สามารถเข้าถึงได้โดยใช้ onmessageเหตุการณ์ในหน้าหลัก ตอนนี้ให้เราเขียนตัวอย่าง bigLoop ของเราโดยใช้ Web Worker ด้านล่างนี้คือหน้าหลัก (hello.htm) ซึ่งจะวางไข่ผู้ปฏิบัติงานบนเว็บเพื่อดำเนินการลูปและส่งคืนค่าสุดท้ายของตัวแปรj -

<!DOCTYPE HTML>

<html>
   <head>
      <title>Big for loop</title>
      
      <script>
         var worker = new Worker('bigLoop.js');
         
         worker.onmessage = function (event) {
            alert("Completed " + event.data + "iterations" );
         };
         
         function sayHello() {
            alert("Hello sir...." );
         }
      </script>
   </head>
   
   <body>
      <input type = "button" onclick = "sayHello();" value = "Say Hello"/>
   </body>
</html>

ต่อไปนี้เป็นเนื้อหาของไฟล์ bigLoop.js สิ่งนี้ใช้ประโยชน์จากไฟล์postMessage() API เพื่อส่งการสื่อสารกลับไปที่หน้าหลัก -

for (var i = 0; i <= 1000000000; i += 1) {
   var j = i;
}
postMessage(j);

สิ่งนี้จะให้ผลลัพธ์ดังต่อไปนี้ -

การหยุด Web Workers

Web Workers ไม่ได้หยุดด้วยตัวเอง แต่เพจที่เริ่มต้นสามารถหยุดพวกเขาได้ด้วยการโทร terminate() วิธี.

worker.terminate();

Web Worker ที่ถูกยกเลิกจะไม่ตอบสนองต่อข้อความหรือทำการคำนวณเพิ่มเติมใด ๆ อีกต่อไป คุณไม่สามารถรีสตาร์ทผู้ปฏิบัติงานได้ แต่คุณสามารถสร้างคนงานใหม่โดยใช้ URL เดียวกัน

การจัดการข้อผิดพลาด

ต่อไปนี้แสดงตัวอย่างของฟังก์ชันการจัดการข้อผิดพลาดในไฟล์ Web Worker JavaScript ที่บันทึกข้อผิดพลาดไปยังคอนโซล ด้วยรหัสการจัดการข้อผิดพลาดตัวอย่างข้างต้นจะเป็นดังต่อไปนี้ -

<!DOCTYPE HTML>

<html>
   <head>
      <title>Big for loop</title>
      
      <script>
         var worker = new Worker('bigLoop.js');
         
         worker.onmessage = function (event) {
            alert("Completed " + event.data + "iterations" );
         };
         
         worker.onerror = function (event) {
            console.log(event.message, event);
         };
         
         function sayHello() {
            alert("Hello sir...." );
         }
      </script>
   </head>
   
   <body>
      <input type = "button" onclick = "sayHello();" value = "Say Hello"/>
   </body>
</html>

กำลังตรวจสอบการรองรับเบราว์เซอร์

ต่อไปนี้เป็นไวยากรณ์ในการตรวจหาคุณสมบัติ Web Worker ที่รองรับในเบราว์เซอร์ -

<!DOCTYPE HTML>

<html>
   <head>
      <title>Big for loop</title>
      <script src = "/js/modernizr-1.5.min.js"></script>
      
      <script>
      function myFunction() {
         
         if (Modernizr.webworkers) {
            alert("Congratulation!! you have web workers support." );
         } else {
            alert("Sorry!! you do not have web workers support." );
         }
      }
      </script>
   </head>
   
   <body>
      <button onclick = "myFunction()">Click me</button>
   </body>
</html>

สิ่งนี้จะให้ผลลัพธ์ดังต่อไปนี้ -