HTML5 - Nhân viên web

JavaScript được thiết kế để chạy trong môi trường đơn luồng, có nghĩa là nhiều tập lệnh không thể chạy cùng một lúc. Xem xét tình huống mà bạn cần xử lý các sự kiện giao diện người dùng, truy vấn và xử lý lượng lớn dữ liệu API cũng như thao tác với DOM.

JavaScript sẽ treo trình duyệt của bạn trong tình huống sử dụng CPU cao. Hãy để chúng tôi lấy một ví dụ đơn giản trong đó JavaScript đi qua một vòng lặp lớn -

<!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>

Nó sẽ tạo ra kết quả sau:

Khi bạn nhấp vào nút Big Loop, nó sẽ hiển thị kết quả sau trong Firefox:

Nhân viên web là gì?

Tình huống được giải thích ở trên có thể được xử lý bằng Web Workers người sẽ thực hiện tất cả các nhiệm vụ tính toán tốn kém mà không làm gián đoạn giao diện người dùng và thường chạy trên các luồng riêng biệt.

Web Worker cho phép các tập lệnh chạy lâu dài không bị gián đoạn bởi các tập lệnh phản hồi với các nhấp chuột hoặc các tương tác khác của người dùng và cho phép các tác vụ dài được thực thi mà không cần năng suất để giữ cho trang phản hồi.

Web Worker là các tập lệnh nền và chúng có dung lượng tương đối nặng và không nhằm mục đích sử dụng với số lượng lớn. Ví dụ: sẽ không phù hợp nếu khởi chạy một công nhân cho mỗi pixel của hình ảnh bốn megapixel.

Khi một tập lệnh đang thực thi bên trong Web Worker, nó không thể truy cập đối tượng cửa sổ của trang web (window.document), điều đó có nghĩa là Web Worker không có quyền truy cập trực tiếp vào trang web và API DOM. Mặc dù nhân viên web không thể chặn giao diện người dùng của trình duyệt, nhưng chúng vẫn có thể tiêu thụ chu kỳ CPU và khiến hệ thống kém phản hồi.

Nhân viên web hoạt động như thế nào?

Web Worker được khởi tạo bằng URL của tệp JavaScript chứa mã mà worker sẽ thực thi. Mã này thiết lập các trình xử lý sự kiện và giao tiếp với tập lệnh tạo ra nó từ trang chính. Sau đây là cú pháp đơn giản:

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

Nếu tệp javascript được chỉ định tồn tại, trình duyệt sẽ tạo ra một chuỗi công nhân mới, được tải xuống không đồng bộ. Nếu đường dẫn đến công nhân của bạn trả về lỗi 404, công nhân sẽ không thành công.

Nếu ứng dụng của bạn có nhiều tệp JavaScript hỗ trợ, bạn có thể nhập chúng importScripts() phương thức lấy (các) tên tệp làm đối số được phân tách bằng dấu phẩy như sau:

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

Khi Web Worker được tạo, giao tiếp giữa web worker và trang mẹ của nó được thực hiện bằng cách sử dụng postMessage()phương pháp. Tùy thuộc vào trình duyệt / phiên bản của bạn, postMessage () có thể chấp nhận một chuỗi hoặc đối tượng JSON làm đối số duy nhất của nó.

Thông báo do Web Worker chuyển được truy cập bằng onmessagesự kiện trong trang chính. Bây giờ chúng ta hãy viết ví dụ về bigLoop bằng cách sử dụng Web Worker. Dưới đây là trang chính (hello.htm) sẽ tạo ra một web worker để thực thi vòng lặp và trả về giá trị cuối cùng của biếnj -

<!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>

Sau đây là nội dung của tệp bigLoop.js. Điều này làm cho việc sử dụngpostMessage() API để chuyển giao tiếp trở lại trang chính -

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

Điều này sẽ tạo ra kết quả sau:

Ngừng nhân viên web

Nhân viên web không tự dừng lại nhưng trang đã bắt đầu họ có thể ngăn họ bằng cách gọi terminate() phương pháp.

worker.terminate();

Một Web Worker bị chấm dứt sẽ không còn trả lời thư hoặc thực hiện bất kỳ tính toán bổ sung nào. Bạn không thể khởi động lại một nhân viên; thay vào đó, bạn có thể tạo một nhân viên mới bằng cách sử dụng cùng một URL.

Xử lý lỗi

Sau đây là ví dụ về chức năng xử lý lỗi trong tệp JavaScript Web Worker ghi lại lỗi vào bảng điều khiển. Với mã xử lý lỗi, ví dụ trên sẽ trở thành như sau:

<!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>

Kiểm tra hỗ trợ trình duyệt

Sau đây là cú pháp để phát hiện hỗ trợ tính năng Web Worker có sẵn trong trình duyệt:

<!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>

Điều này sẽ tạo ra kết quả sau: