Như các bạn có thể đã biết, javascript là một ngôn ngữ single-threaded. Trên web browser, mỗi cửa sổ hoặc mỗi tab chỉ có 1 luồng xử lý duy nhất. Trở ngại của single-thread trên browser đó là khi code đang được thực thi, bạn sẽ ko thể làm gì khác, UI của bạn sẽ bị khoá cứng.
Có một giải pháp quen thuộc để giải quyết vấn đề này đó Event Loop, asynchronous event. Quen thuộc nhất đó AJAX. Tuy vậy, AJAX cũng vẫn chỉ giải quyết đuợc một phần vấn đề. Ví dụ khi các bạn sử dụng AJAX, cụ thể, các bạn thực hiện một GET request lên server, các bạn bind một callback function xử lý dữ liệu cho event khi có response trả về, nói nôm na theo ngôn ngữ của con người là "ê, khi nào dữ liệu về thì xử lý như thế này nhé".
Chúng ta rung đùi làm việc khác, kệ cho response về lúc nào thì về. Nếu dữ liệu nhỏ, callback function của bạn được xử lý cái roẹt. Tuy nhiên nếu dữ liệu lớn, lúc này nhược điểm sẽ lộ ra, UI của bạn sẽ đơ cứng, đơ cho đến khi callback function của bạn chạy xong. Vấn đề do đâu, do callback function vẫn phải chạy trên luồng duy nhất của phiên làm việc.
Phiên bản HTML5 cung cấp cho chúng ta một loạt APIs rất hữu ích và một trong số chúng giúp giải quyết vấn đề nêu trên, đó là Web Worker. Web Worker cho phép xử lý script ở một luồng dưới background tách biệt với luồng chính (chủ yếu là UI), giúp UI ko bị chậm lại hoặc khoá cứng khi phải xử lý dữ liệu nặng.
Xin nhấn mạnh lại là JS vẫn đơn luồng mà thôi, còn Web Workers là một APIs được cung cấp bới trình duyệt giúp giải quyết nhược điểm đơn luồng của JS.
Chúng ta có 3 loại Worker chính:
Dedicated Worker Worker chỉ dùng được trong nội bộ main thread. Dedicated worker hiện đã được hỗ trỡ trên ~95% các trình duyệt.
Shared Worker Worker có thể được truy cập bởi nhiều process khác nhau như tab khác nhau, iframe khác nhau, miễn sao chúng cùng một origin domain. Nó cũng phức tạp hơn Dedicated Worker, chúng ta cần định nghĩa cổng cho các lần giao tiếp. Shared worker mới được hỗ trợ ở mức khá hạn chế, mới chỉ khoảng 43% các trình duyệt
Mình sẽ sử dụng Dedicated Worker làm ví dụ vì cách dùng của nó đơn giản nhất. Worker nói chung và Dedicated Worker nói riêng được sử dụng thông qua javascript, được khởi tạo bằng constructor Worker(). Worker sẽ gọi vào 1 file javascript chứa đoạn code chúng ta muốn xử lý ở luồng worker, tách biệt với luồng chính do window object nắm giữ. Dữ liệu được gửi qua lại giữa main thread và worker thread qua hệ thống message sử dụng method postMessage(), và được nhận thông qua event handler onmessage ở cả 2 phía. Dữ liệu này được copy và gửi đi chứ ko dùng chung.
Sau đây là 1 ví dụ nhỏ sử dụng Dedicated Worker.
<button onclick="calculate()">calculate</button>
<script>
function calculate() {
worker.postMessage({'data': [1, 2, 3, 4]});
}
var worker = new Worker('calculate-average.js');
worker.addEventListener('message', function(message) {
console.log(message.data);
}, false);
</script>
function calculateAverage(data) {
// do calculating average number
}
self.addEventListener('message', function(e) {
var data = e.data;
var result = calculateAverage(data);
self.postMessage(result);
}, false);
Trong worker thread chúng ta có thể dùng được:
Hạn chế là chúng ta sẽ không thể truy cập đến:
Tổng quan thì chúng ta nên sử dụng Web Worker cho các tác vụ tốn cpu. Cụ thể hơn:
Unpublished comment
Viết câu trả lời