Công nhân Web trong TypeScript
Bài viết này giải thích về công nhân Web trong TypeScript.
Bạn có thể tìm hiểu về khái niệm Web Workers
và các mẹo sử dụng khác nhau với ví dụ.
YouTube Video
Công nhân trong TypeScript
Trong TypeScript, một công nhân (Worker
) là cơ chế thực hiện xử lý trong nền, tách biệt khỏi luồng chính, sử dụng API Công nhân Web của JavaScript. Điều này cho phép thực hiện các tính toán nặng và tác vụ bất đồng bộ mà không ảnh hưởng đến hoạt động của giao diện người dùng.
Công nhân (Worker
) hoạt động song song với luồng chính (luồng giao diện người dùng) và có thể trao đổi dữ liệu giữa các luồng thông qua tin nhắn. Ngay cả trong TypeScript, bạn cũng có thể sử dụng công nhân (Worker
) khi viết mã an toàn về kiểu.
Cách sử dụng cơ bản của Công nhân
-
Tạo một Công nhân
Tạo một thể hiện công nhân (
Worker
) và thực thi tập lệnh đã chỉ định. Thông thường, tập lệnh được định nghĩa trong một tệp riêng biệt. -
Trao đổi Tin nhắn
Gửi và nhận tin nhắn giữa luồng chính và luồng công nhân (
Worker
) bằng cách sử dụngpostMessage
vàonmessage
.
Ví dụ: Triển khai Công nhân Cơ bản
- worker.ts: Tập lệnh cho Công nhân
1// worker.ts
2self.onmessage = (event) => {
3 const data = event.data;
4 const result = data.num1 + data.num2;
5 self.postMessage(result); // Return the result to the main thread
6};
- main.ts: Tập lệnh để sử dụng Công nhân trong Luồng Chính
1// main.ts
2const worker = new Worker(
3 new URL('./worker.ts', import.meta.url),
4 { type: 'module' }
5);
6
7worker.onmessage = (event) => {
8 console.log("Result from worker:", event.data); // Receive message from the worker
9};
10
11worker.postMessage({ num1: 10, num2: 20 }); // Send message to the worker
- Trong ví dụ này,
worker.ts
chạy trong một luồng riêng biệt, tính tổng củanum1
vànum2
, và trả kết quả về cho luồng chính. Luồng chính nhận kết quả và xuất nó ra console. - Khi bạn chỉ định
type: 'module'
, script Worker sẽ được hiểu là một ES module, cho phép bạn sử dụngimport
vàexport
. Điều này cho phép bạn xử lý cấu trúc module mà không cần sử dụngimportScripts()
truyền thống.
Các điểm cần lưu ý khi sử dụng Công nhân trong TypeScript
Thêm Định nghĩa Kiểu
Trong TypeScript, xác định các kiểu dữ liệu để đảm bảo tương tác an toàn về kiểu trong quá trình gửi và nhận tin nhắn.
1// Define data types
2interface WorkerData {
3 num1: number;
4 num2: number;
5}
6
7interface WorkerResult {
8 result: number;
9}
10
11// worker.ts
12self.onmessage = (event: MessageEvent<WorkerData>) => {
13 const data = event.data;
14 const result = data.num1 + data.num2;
15 const message: WorkerResult = { result };
16 self.postMessage(message); // Send the result in a type-safe manner
17};
18
19// main.ts
20const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
21
22// Type the event from the worker
23worker.onmessage = (event: MessageEvent<WorkerResult>) => {
24 console.log("Result from worker:", event.data); // event.data is number
25};
26
27// Send typed data to the worker
28const message: WorkerData = { num1: 10, num2: 20 };
29worker.postMessage(message);
- Bằng cách chỉ định tham số kiểu của
MessageEvent
, bạn có thể xác định rõ ràng loại dữ liệu sẽ nhận. Điều này cho phép trao đổi dữ liệu một cách an toàn về kiểu.
Thiết Lập Webpack hoặc Vite
Khi sử dụng Worker
trong TypeScript, có thể cần các bộ bundler như Webpack
hoặc Vite
. Bằng cách sử dụng các công cụ này, bạn có thể đóng gói đúng cách tập lệnh Worker
và làm cho nó khả dụng từ luồng chính.
Ví dụ, khi sử dụng Vite
, hãy sử dụng import.meta.url
để nhập chính xác tệp Worker
.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
- Điều này đảm bảo rằng tập lệnh
Worker
đã được đóng gói sẽ được tải chính xác, cho phép xử lý tận dụngWorker
.
Các lưu ý về truyền tin nhắn và tính đồng thời
-
Sao chép dữ liệu
Khi gửi và nhận tin nhắn giữa luồng chính và luồng
Worker
, dữ liệu sẽ được sao chép. Khi xử lý dữ liệu phức tạp như đối tượng, cần cân nhắc về hiệu quả. Việc thường xuyên trao đổi lượng lớn dữ liệu có thể làm giảm hiệu suất. -
Đối tượng
Transferable
Một số đối tượng như
ArrayBuffer
được gọi là đối tượngTransferable
. Các đối tượngTransferable
có thể được chuyển sang Worker thay vì sao chép khi gửi tin nhắn. Điều này cho phép bạn tránh việc phải gánh nặng sao chép dữ liệu.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3const buffer = new ArrayBuffer(1024);
4worker.postMessage(buffer, [buffer]); // Transfer ownership to the Worker
5
6console.log(buffer.byteLength); // 0 (ownership moved)
-
Bằng cách truyền
[buffer]
làm đối số thứ hai choworker.postMessage()
,buffer
sẽ được chuyển đến Worker thay vì bị sao chép. -
Sau đó,
buffer
trên luồng chính sẽ trở nên rỗng (cóbyteLength
là 0) và chỉ có thể được Worker sử dụng.
Kết thúc một Worker
Worker
nên được kết thúc sau khi sử dụng để giảm thiểu tiêu thụ bộ nhớ. Bạn có thể kết thúc một Worker
bằng cách sử dụng phương thức terminate
.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2// ...
3
4worker.terminate(); // Terminate the Worker
- Đoạn mã này dừng Worker bằng cách sử dụng phương thức
terminate
.
Xử lý ngoại lệ trong Worker
Nếu xảy ra lỗi trong một Worker
, bạn có thể xử lý lỗi bằng cách sử dụng sự kiện onerror
.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3worker.onerror = (error) => {
4 console.error("Error in Worker:", error.message);
5};
- Đoạn mã này bắt và xử lý lỗi xảy ra bên trong Worker bằng sự kiện
onerror
.
Tóm tắt
Bằng cách sử dụng Worker
trong TypeScript, bạn có thể thực hiện các tác vụ nặng trong nền trong khi giữ cho luồng chính mượt mà. Bằng cách sử dụng các định nghĩa kiểu, việc trao đổi tin nhắn cũng có thể được thực hiện một cách an toàn kiểu. Bằng cách chú ý đến việc trao đổi dữ liệu và quản lý luồng, bạn có thể đạt được cải tiến hiệu suất và tính đồng thời hiệu quả.
Bạn có thể làm theo bài viết trên bằng cách sử dụng Visual Studio Code trên kênh YouTube của chúng tôi. Vui lòng ghé thăm kênh YouTube.