HTML5: Web Worker

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

WEB WORKER

JavaScript được thiết kế để chạy trong một môi trường đơn luồng, điều này có nghĩa là trong cùng một thời điểm sẽ không thể chạy được nhiều kịch bản (script) một lúc. Giả sử bạn cần xử lý các sự kiện giao diện người dùng trình duyệt phức tạp, trong đó cần truy vấn và xử lý một lượng lớn dữ liệu API và các thao tác DOM, khi đó Javascript có thể sẽ treo trình duyệt của bạn nếu nó tiêu tốn quá nhiều tài nguyên CPU.

Web Worker là gì?

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

Về mặt bản chất, Web Worker là một tập lệnh JavaScript (JS), tập lệnh này không làm ảnh hưởng đến hiệu năng của trang web, nó cho phép các kịch bản có thể chạy trong thời gian dài mà không bị gián đoạn bởi các kịch bản có đáp ứng như là các cú nhấn chuột hay những tương tác người dùng khác, và cho phép những tác vụ phức tạp được thực thi mà không hề làm giảm hiệu suất để đảm bảo vẫn giữ được tính hồi đáp của các trang web.

Web Worker là các kịch bản nền và nó tương đối nặng nề, cho nên ta không nên dùng nó với số lượng lớn. Ví dụ như ta không nên tạo worker cho mỗi điểm ảnh với một tấm ảnh có kích thước vài megapixel.

Khi một kịch bản đang được thực hiện trong Web Worker thì nó không thể truy cập được đối tượng window của trang web (window.document), điều này có nghĩa là Web Worker không thể trực tiếp truy cập được tới trang web và API DOM. Mặc dù Web Worker không thể ngăn chặn các giao diện người dùng trình duyệt, nhưng nó vẫn có thể làm giảm tốc độ CPU và làm giảm khả năng đáp ứng của hệ thống.

Web Worker làm việc như thế nào?

Web Worker được khởi tạo với một URL là một tập tin JavaScript, file này chứa mã lệnh mà nó sẽ thực thi. Mã lệnh này có nhiệm vụ thiết lập bộ lắng nghe sự kiện và giao tiếp với kịch bản đã sinh ra nó từ trang chính.

Câu lệnh dưới đây thể hiện một ví dụ đơn giản về cách tạo một đối tượng worker:

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

Nếu tập tin javascript đã chỉ định tồn tại, thì trình duyệt sẽ sinh ra một luồng worker mới, và được tải xuống không đồng bộ. Còn nếu đường dẫn tới worker trả về lỗi 404 thì worker sẽ được hiểu là không có tác dụng.

Nếu ứng dụng của bạn có nhiều tập tin hỗ trợ javascript thì bạn có thể sử dụng phương thức importScripts() để nhập chúng bằng cách đặt tên các file vào phần đối số của phương thức này và dùng dấu (,) làm phần phân cách. Ví dụ:

importScripts("js1.js", "js2.js");

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

Thông điệp thông qua web worker được truy cập bằng cách sử dụng sự kiện onmessage trong trang chính. Bây giờ ta sẽ viết một ví dụ sử dụng web worker, trong đó trang chính là demo.html và nó sẽ sinh ra một web worker để thực hiện vòng lặp và trả về giá trị cuối cùng của biến j.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Vòng lặp lớn</title>
<script>
var worker = new Worker('worker.js');
worker.onmessage = function (event) {
  alert("Đã lặp " + event.data + " lần.");
};
worker.onerror = function (event) {
  console.log(event.message, event);
};
function fhello() {
  alert("Chào bạn ..." );
}
</script>
</head>
<body>
<input type="button" onclick="fhello();" value="Nói xin chào"/>
</body>
</html>

Dưới đây là nội dung của tập tin worker.js. Trong tập tin sử dụng phương thức postMessage() để truyền thông tin trở về trang chính.

for (var a = 0; a <= 1000; a++) {
  var j = a;
}
postMessage(j);

Bây giờ ta đặt hai tập tin demo.html và demo.js trong cùng một thư mục và thử truy cập bằng trình duyệt phiên bản mới nhất.

Ngắt Web Worker

Web Worker không tự ngắt được chính bản thân nó, nhưng trang mà đã kích hoạt nó có thể ngắt được nó bằng phương thức terminate().

worker.terminate();

Nếu đã ngắt Web Worker thì nó sẽ không thể hồi đáp thông điệp cũng như giải quyết bất kỳ hoạt động tính toán nào khác bởi tất cả các tài nguyên của trình duyệt cũng như của máy tính có liên quan sẽ được giải phóng. Ta không thể kích hoạt trở lại được một Web Worker, nhưng thay vào đó ta có thể tạo một đối tượng Web Worker mới bằng cách sử dụng cùng một URL.

Xử lý lỗi

Sau đây là một ví dụ về chức năng xử lý lỗi trong tập tin JavaScript Web Worker trong đó lỗi được đưa ra trình duyệt.

worker.onerror = function (event) {
  console.log(event.message, event);
};

Kiểm tra sự hỗ trợ của trình duyệt

Cú pháp sau đây được dùng để kiểm tra xem trình duyệt có hỗ trợ Web Worker hay không. Một thông báo thích hợp được đưa ra sẽ cho ta biết điều này.

function myFunction() {
  if (Modernizr.webworkers) {
    alert("Xin chúc mừng! Trình duyệt này có hỗ trợ Web Worker.");
  }
  else {
    alert("Trình duyệt này không hỗ trợ Web Worker." );
  }
}

Ví dụ áp dụng Web Worker

Dưới đây là ví dụ hoàn chỉnh áp dụng Web Worker. Tập tin demo.html chứa đoạn mã sau đây:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Vòng lặp lớn</title>
<script src="js/modernizr-1.5.min.js"></script>
<script>
var worker = new Worker('demo.js');
worker.onmessage = function (event) {
  alert("Đã lặp " + event.data + " lần.");
};
worker.onerror = function (event) {
  console.log(event.message, event);
};
function fnoiXinChao() {
  alert("Chào bạn ..." );
}
function fCheck() {
  if (Modernizr.webworkers) {
    alert("Xin chúc mừng! Trình duyệt này có hỗ trợ Web Worker.");
  }
  else {
    alert("Trình duyệt này không hỗ trợ Web Worker." );
  }
}
function fNgat(){
   worker.terminate();
}
</script>
</head>
<body>
<input type="button" onclick="fnoiXinChao();" value="Nói xin chào" />
<input type="button" onClick="fCheck();" value="Check support" />
<input type="button" onClick="fNgat();" value="Ngắt Web Worker" />
</body>
</html>

Còn đây là đoạn mã chứa trong tập tin demo.js:

// JavaScript Document
for (var i = 0; i <= 1000000000; i += 1) { //lặp 1 tỷ lần
  var j = i;
}
postMessage(j);

Phương thức postMessage() có nhiệm vụ đưa giá trị chứa trong biến j về trang demo.html và nó được lưu vào biến event.data.

Bạn nên thực thi ví dụ trên trên trình duyệt Firefox hoặc Safari, vì các trình duyệt khác hiện tại còn đang chưa hỗ trợ kỹ thuật Web Worker. Dưới đây là một số hình ảnh minh họa việc thực thi ví dụ trên trình duyệt Firefox.

Trong trường hợp bạn nhấn nút F5 để tải lại trang web thì thông báo "Đã lặp 1000000000 lần" lại xuất hiện sau khoảng vài giây. Nhưng nếu trong quá trình chờ thông báo này xuất hiện lại mà bạn nhấn nút Ngắt Web Worker thì thông báo sẽ không hiện lại nữa.

» Tiếp: Nhóm nội dung
« Trước: Sự kiện Media
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!