WORKER LÀ GÌ

     

Introduction

JavaScript là một môi trường thiên nhiên đơn luồng (single-threaded environment), hoàn toàn có thể hiểu dễ dàng là tại một thời điểm nhất mực chỉ gồm một script được thực thi. Trong thời hạn gần đây, việc áp dụng JavaScript trong câu hỏi xây dựng những ứng dụng website trở nên phổ cập hơn khi nào hết, các các bước được đưa đa phần về phía client. Tính chất đơn luồng của JavaScript là một trong cản trở so với việc trên vì chưng nó làm hình ảnh hường khá khủng đến hiệu năng của các ứng dụng web. Một ví dụ đơn giản là những ứng dụng website thường cần truy vấn database, tiến hành các đổi khác phức tạp trên DOM, cách xử trí các event liên quan cho UI với request đến những API mặt thứ tía - khá nhiều việc cho một thread.

Bạn đang xem: Worker là gì

Trong thừa khứ họ thường thực hiện setInterval , setTimeout, XMLHttpRequest với event handlers để triển khai quá trình nhất quán hóa (concurrency). Sử dụng các trick trên chất nhận được thực thi code một cách bất đồng bộ, dẫu vậy nó không trọn vẹn không có nghĩa họ đang triển khai concurrency một giải pháp đầy đủ. Bây giờ WEB API hỗ trợ một công cụ tốt hơn để triển khai multi-threading task một cách hiệu quả hơn - Web Workers. Website Workers chưa phải là một technology mới khi nó thành lập cùng cùng với HTML5, nhiệm vụ chính của các Workers là thực hiện các scripts cách xử trí các quá trình nặng (querying API, complex mathematical computations) làm việc background và tách biệt với các scripts liên quan đến UI (thường là Main Thread). Việc này có thể chấp nhận được long-running scripts được xúc tiến mà không gây ảnh hướng mang lại trải nghiệm của bạn dùng.

Trong bài viết này bản thân sẽ trình diễn những kiến thức và kỹ năng cơ bạn dạng liên quan đến Web Workers, bí quyết hoạt động, các use-cases cũng tương tự những để ý khi thực hiện công nắm này lúc phát triển.

Web Workers

Definition

Web Worker (hay Worker) là một đối tượng người tiêu dùng JavaScript được tạo bởi việc thực hiện Worker constructor (e.g Worker, SharedWorker, AudioWorker) với tham số là tên (đường dẫn) mang đến một JavaScript file. JavaScript file kia chứa những logic được khởi chạy phía bên trong thread của worker vừa tạo. Script phía bên trong Worker sẽ tiến hành thực thi sinh sống background và tách biệt khỏi thread bao gồm của website application.

Trong nội dung bài viết này, bọn họ sẽ nhà yếu khám phá về Worker (DedicatedWorker). Để ban đầu chúng ta sẽ tạo nên một instance của DedicatedWorker cùng hiển thị nó vào console. Để solo giản bọn họ giả sử rất nhiều logic bên dưới được thực hiện bên phía trong script tag của một tệp tin HTML.

var worker = new Worker("prime.js")console.log(worker)console.log(this)

*

Sau khi đã log Worker instance và context hiện nay tại chúng ta cũng có thể thấy một số trong những API cơ phiên bản của Worker như onerror, onmessage, postMessage với terminate. Hồ hết API này sẽ tiến hành đề cập mang lại trong phần sau của bài bác viết. Chăm chú rằng context lúc này là global context xuất xắc Window. Hiện thời chúng ta sẽ sửa đổi file prime.js với thêm một cái alert đơn giản alert("Hello from the outside!") cùng reload lại trình duyệt. Quan sát kết quả trong console ta sẽ thấy một error.

*

Chúng ta sử dụng JavaScript dẫu vậy không thể truy cập được alert function. Tại sao ở đây là prime.js sẽ tiến hành thực thi phía bên trong một context khác với Window. Script bên trong worker được phép truy cập đến các DOM API tuy nhiên không phải toàn bộ các API đều truy vấn được phía bên trong Worker. Để chất vấn context hiện tại tại, chúng ta sẽ thêm loại lệnh đơn giản và dễ dàng sau vào bên trong prime.js: console.log(this). Kết quả thu được đã như hình mặt dưới:

*

Để ý rằng context hiện tại đã được thay đổi thành DedicatedWorkerGlobalScope thay bởi Window (nếu thực hiện SharedWorker context đã là SharedWorkerGlobalScope). Bên phía trong context của các Worker chúng ta có thể thực hiện các logic JavaScript thông thường. Mặc dù nhiên chúng ta không thể thực hiện các làm việc trên DOM một bí quyết trực tiếp, cũng tương tự không thể truy cập đến một trong những method cùng property của window object. Ngoài các giới hạn trên, bọn họ vẫn có thể truy cập đến không ít API quan trọng đặc biệt như:

Communication Between Threads

Worker script sẽ tiến hành thực thi bởi một background thread tách bóc biệt và chạy tuy vậy song với thread chính. Trong nhiều trường hợp họ cần truyền tài liệu từ những background worker cho main thread để giải pháp xử lý và ngược lại. Nói giải pháp khác, chúng ta cần coordinate (điều phối) mối quan hệ giữa những thread cùng với nhau.

Nếu bạn đã từng thao tác làm việc với Concurrency vào Java, rất có thể bạn đã tìm đến hai có mang khá cơ bản là Producer cùng Consumer. Khi lập trình với thread hai quá trình bạn thường phải làm đó là synchronize với coordinate những thread. Trong Java câu hỏi đó sẽ được thực hiện bằng phương pháp sử dụng Semaphores (một số cách thức cụ thể kia là thực hiện wait-notify hoặc wait-notifyAll). Trong mối quan hệ Producer/Consumer, việc coordinating để giúp đỡ cho việc truy vấn share resources trở nên bao gồm xác.

Quay trở về với Worker, nguyên lý coordinate giữa những worker cùng main thread sẽ là message-passing sử dụng sự kiện model. Main thread có thể gửi tin tức đến các Worker trải qua postMessage. PostMessage đã nhận thông số đầu vào là một trong string hoặc một JSON object. Main thread với Worker sẽ nhận thông tin bằng việc lắng nghe message event, và truy cập dữ liệu thông qua event.data.

var worker = new Worker("foo.js")worker.postMessage("Hello from main thread")worker.addEventListener("message", function (e) console.log(e.data) // Hello from worker, false)// foo.jsself.addEventListener("message". Function (e) console.log(e.data) // Hello from main thread self.postMessage("Hello from worker"), false)// another way khổng lồ listen for the ventself.onmessage = function (e) ...Trong context của một Worker, this cùng self đa số chỉ mang lại global scope - WorkerGlobalScope

Lưu ý rằng dữ liệu truyền giữa Main Thread và các Worker đang được xào luộc (copied) chứ không được chia sẻ (shared). Giả sử tài liệu truyền đi từ bỏ Main Thread và Worker là 1 trong JSON object cất name property, property này sẽ truy cập được sống cả Main Thread cùng Worker mặc dù giá trị sẽ là khác nhau. Trên thực tế, dữ liệu sẽ được serialized trước khi được gởi đến cho các Worker và dữ liệu đó sẽ được de-serialized sau đó. Tài liệu không được chia sẻ nên sẽ tạo nên ra một bạn dạng sao sau các lần được truyền đi. Đó cũng là nguyên nhân tại sao chúng ta nên để ý khi dùng Worker vị nó tương đối tốn khoáng sản của hệ thống. Trong phần tiếp theo của bài xích viết, bọn họ sẽ đề cập cho một cách thức để xử lý vấn đề này.

Transferrable objects

Hầu hết những trình duyệt hiện giờ đều thiết đặt structured cloning algorithm cho phép họ sử dụng hồ hết kiểu dữ liệu tinh vi hơn cho Worker, ví dụ như: Blob, File, FileList, ArrayBuffer, Map, với JSON objects. Mục tiêu của structured cloning algorithm là làm cho quá trình xào luộc các object phức tạp trở nên hiệu quả hơn. Tuy nhiên nên ghi nhớ rằng, tài liệu vẫn sẽ tiến hành copied trong mỗi lần gọi postMessage. Giả sử họ cần gửi một file khoảng tầm 100MB giữa Worker cùng Main Thread, vấn đề này sẽ gây tốn tương đối nhiều tài nguyên hệ thống.

Các kiểu dữ liệu trên hỗ trợ nhiều tuyển lựa mềm dẻo hơn khi định dạng dữ liệu truyền đi, mặc dù quá trình copy hoàn toàn có thể kéo dài nếu tài liệu có size quá lớn. Transferrable objects là một cách để khắc phục vụ việc này. Khi áp dụng transferrable objects tài liệu sẽ chỉ biến đổi context và không bị copy lại. đọc một cách 1-1 giản, nó hệt như pass-by-reference (thay vày pass-by-value) trong ngôn từ C.

ArrayBuffer thường hay được dùng trong câu hỏi trao đổi dữ liệu giữa Worker và Main Thread. Thực hiện ArrayBuffer chúng ta có thể truyền binary data ví như ảnh, âm thanh tác dụng hơn, rứa vì thực hiện base64 encoding như trước.

Syntax đến postMessage đang như sau:

worker.postMessage(message, );Trong cấu tạo trên, message vẫn là dữ liệu được gửi mang lại Worker, nó không nhất thiết phải là 1 trong những ArrayBuffer, nó là dữ liệu mà chúng ta cũng có thể lấy ra áp dụng e.data. Tham số sản phẩm công nghệ hai đang là những transferrable objects mà bọn họ muốn gửi quyền sở hữu. Lý do chúng ta nói chuyển quyển cài (ownership) là do transferrable object sau khi được gửi từ Main Thread quý phái Worker thì chỉ rất có thể sử dụng được bên Worker với ngược lại.

Các bạn cũng có thể tìm hiều một ví dụ chi tiết về việc sử dụng Transferrable objects đến Web Worker tại đây

Dedicated Worker

Trong phần này của bài bác viết, họ sẽ tìm hiểu cách sử dụng DedicatedWorker. Về SharedWorker các bạn cũng có thể tìm hiều thêm tại đây

Trước khi tò mò cách sử dụng, bọn họ cần chăm chú rằng Dedicated Worker đang chỉ được sử dụng bởi 1 script duy nhất, không giống với Shared Worker lúc nó có thể được áp dụng bởi những script khác biệt (cùng tên miền với Worker). Tuy nhiên hiện trên DedicatedWorker thịnh hành hơn khá nhiều so cùng với SharedWorker và một trình duyệt y như Safari với Internet Explorer không cung cấp SharedWorker trong bất kể phiên bạn dạng nào tính mang lại thời điểm nội dung bài viết này.

Xem thêm: Công Ty Fmcg Là Gì - 5 Xu Hướng Kinh Doanh, Marketing Ngành Fmcg

Worker Detection

Trước khi thực hiện Worker họ cần soát sổ xem trình duyệt bây giờ có cung cấp Worker tuyệt không. Do Worker constructor function được truy cập thông qua window object, bạn có thể kiểm tra như sau:

if (window.Worker) var worker = new Worker("foo.js")// Using Modernizrif (Modernizr.webworkers) var worker = new Worker("bar.js")Create New WorkerViệc tạo bắt đầu một Dedicated Worker instance là khá 1-1 giản, họ chỉ cần áp dụng Worker() constructor function với tham số nguồn vào là URI mang đến script sẽ được thực thi bên trong worker thread:

if (window.Worker) var worker = new Worker("./math/prime.js")Exchange MessagesTrong phần trước khi đề cập mang lại message-passing vào Worker, bọn họ đã đi qua một ví dụ dễ dàng và đơn giản minh họa quy trình trao đổi dữ liệu giữa Main Thread và Worker. Sau khi đã bao gồm một instance của Worker, nhằm khởi đụng Worker đó bọn họ sẽ thực hiện postMessage function. Giữ ý, vào trường hợp không tồn tại dữ liệu được truyền đi, chúng ta cần pass một empty string như argument đầu tiên cho postMessage. Nguyên nhân là việc thiết đặt function trên giữa các trình cẩn thận là không hoàn toàn giống nhau. Một số trình phê chuẩn như Firefox đã báo lỗi khi bọn họ không truyền tham số mang đến postMessage

worker.postMessage("")worker.postMessage("Hello World!")worker.postMessage( name: "Foo Bar", age: 100000 )Sau khi vẫn kick off Worker, bọn họ sẽ sử dụng event Model để trao đổi dữ liệu. Bí quyết thường được áp dụng là lắng nghe message sự kiện thay vì thực hiện onmessage property. Bọn họ sẽ đi qua 1 ví dụ nữa, tuy vậy thay vì đàm phán string bọn họ sẽ sử dụng object cho dữ liệu.

// index.htmlbutton onclick="greeting()">Greeting/button>button onclick="stop()">Stop Worker/button>output id="result">/output>script> if (window.Worker) var worker = new Worker("worker.js") worker.addEventListener("message", function (e) document.getElementById("result").textContent = e.data , false) function greeting() worker.postMessage( "name": "Anonymous", "age": 25 ) function stop() worker.terminate() /script>// worker.jsself.addEventListener("message", function (e) var data = e.data var mesage = "Hello! I am " + data.name + "I am " + data.age + " years old" self.postMessage(message), false)Trong ví dụ như trên Main Thread sẽ gửi cho Worker một object chứa tin tức về một bạn nào đó. Trách nhiệm của Worker đang là tạo thành một câu reviews về tín đồ đó là trả lại mang đến Main Thread. Main Thread sẽ lắng nghe message sự kiện và in câu chào đó thực hiện output HTML tag. Để dừng worker chúng ta sử dụng terminate function. Bọn họ cũng sử dụng một giao diện dễ dàng và đơn giản với nhì button đến hai việc là hiển thị câu chào và ngừng worker.

Terminate Worker

Để giới hạn một worker họ có hai bí quyết sau (chúng ta rất có thể ngắt liên kết từ Main Thread hoặc từ bên Worker):

Sử dụng terminate function bên trên Worker instance.Sử dụng close bên phía trong Worker script.

// Terminate worker using workerworker.terminate()// Terminate worker inside worker scriptself.close()Hande ErrorsTrong những ví dụ trên chúng ta chưa đề cập tới việc xử lý các error hoàn toàn có thể xảy ra. Tương tự quy trình nhận và cách xử lý dữ liệu, họ sẽ lắng nghe error event và handle các error trong callback:

worker.addEventListener("error", function (e) console.log(e) // Handle the error, false)Event object trả về xúc tiến ErrorEvent interface, và cung cấp cho chúng ta khá nhiều tin tức hữu ích:

lineno: địa chỉ của dòng code gây ra lỗi.filename: thương hiệu của file mà lại lỗi xảy ra.message: tế bào tả cụ thể về lỗi sẽ xảy ra.Import Scripts

Bên vào một Worker, chúng ta có thể sử dụng this.importScripts(urls) để import những thư viện với dependency cần thiết cho worker script.

this.importScripts("foo.js")this.importScripts("foo.js", "bar.js", "fizz.js")Lưu ý rằng chúng ta không thể import một vài thư viện như jQuery bên trong worker script bằng phương pháp này. Vào phần đầu của nội dung bài viết chúng ta từng đề cập tới sự việc không thể truy cập cục bộ các API bên phía trong window object (do một trong những vấn đề về bảo mật), nếu sử dụng this.importScripts("jquery.js") sẽ có lỗi xảy ra.

Subworkers

Một Worker tất cả thể chứa nhiều Worker nhỏ (Subworker) khác nhau, mang lại phép chúng ta chia bé dại hơn nữa một task bên trong một Worker. Khi áp dụng Subworker họ cần để ý một số vụ việc sau:

Subworkers đề nghị được tàng trữ cùng origin so với Worker gốc.URI vào Subworkers sẽ là đường dẫn tương đối so với địa chỉ của Worker gốc.

Hầu hết các trình chăm chút đều cung ứng một process riêng cho từng Worker. Trước lúc sử dụng thêm 1 Worker bọn họ cần quan tâm đến tài nguyên bây giờ của hệ thống. Tại sao là dữ liệu truyền đi giữa giải pháp Worker vẫn được coppy chứ không phổ biến một nguồn, sử dụng vô số Worker sẽ không mang lại hiểu quả cùng làm tác động đến performance của ứng dụng.

Limitations

Worker là 1 công thay khá hữu ích, mặc dù nó cũng có một số tiêu giảm nhất định, vào phần này họ sẽ nhắc đến một vài vấn đề gặp gỡ phải khi thực hiện Worker.

Same Origin

Tất cả những Worker script bắt buộc được served từ cùng một domain như script mà lại ở kia Worker được khởi tạo. Điều này cũng áp dụng cho tất cả loại protocol sẽ sử dụng.

Limited Access

Logic bên trong Worker sẽ là bóc biết đối với Main Thread, cho nên vì vậy Worker hoàn toàn có thể sẽ không truy vấn được đến một trong những DOM APIs (như đã nói đến trong phần đầu của bài xích viết). Một cách để thực hiện đa số việc tương quan đến Main Thread là nhờ cất hộ message đến nó trường đoản cú Worker thông qua postMessage.

Restricted Local Access

Worker vẫn không vận động nếu web page được server trực tiếp trường đoản cú filesystem. Họ cần có một server nếu còn muốn sử dụng Worker.

Xem thêm: Top 25+ Hình Nền Trong Suốt Iphone Xs Max, Cách Làm Màn Hình Trong Suốt Iphone

Conclusion

Trong nội dung bài viết này bản thân có trình diễn một giải pháp khá cơ bản về web Worker (tập trung chủ yếu vào Dedicated Workers): định nghĩa, bí quyết hoạt động, biện pháp truyền download dữ liệu, cũng tương tự những giảm bớt là để ý khi sử dụng Web Worker. ước ao rằng bài viết sẽ giúp ích được một trong những phần nào kia cho các bạn trong quá trình sau này.