SUBSCRIBE NEWSLETTERS

Xem nhiều nhất

Sử dụng Web Worker để chạy ngầm đa luồng trong Javascript

Sử dụng Web Worker để chạy ngầm đa luồng trong Javascript

Ngày đăng 12/2/2020
4 phút đọc
395 lượt xem
Duclux.Com
Tác giảDucLux.Com

Hôm nay được giao nhiệm vụ thực hiện page login. Nhiệm vụ đơn giản thế này: Đầu tiên gọi request lên server để lấy về token về client. Trong JWT token thường có một field gọi là exp (expired), tức là thời gian token hết hạn. Khi token expired thì yêu cầu phải tự động logout.

Ý tưởng của mình là dùng setTimeout để setup 1 sesstion login với thời gian truyền vào bằng với thời điểm nhận token cho tới khi token hết hạn. Nhưng mà nếu sử dụng setTimeout trong thời gian dài có thể ảnh hưởng tới performance của app. Thế là mình nghĩ tới Worker. Đây là một Api được hỗ trợ hầu hết các trình duyệt. Pollyfill nó rất tốt. Mình chọn nó vì nó chạy khác luồng với Js của mình. Và giao tiếp thông qua message. Như vậy mình có thể tối ưu hóa performance của app. Trong bài này mình không giới thiệu tới các bạn quy trình login, mình chỉ tập trung vào nội dung chính như tiêu đề bài viết là sử dụng web Worker như thế nào mà thôi.

Giới thiệu sơ về web worker

Web worker là một tác vụ javascript chạy ngầm dưới trang web, không làm ảnh hưởng đến hiệu năng của trang web hiện tại.

Như bạn đã biết Javascript chỉ có một luồng. Nên nếu chúng ta thực hiện nhiều tác vụ cùng một lúc thì ảnh hưởng đến performance. Có thể làm đứng trình duyệt. Nếu những tác vụ nào có thể chạy ngầm được nên cho vào worker để nó chạy ngầm vào một luồng khác không ảnh hưởng tới luồng hiện tại (main thread). Bạn có thể hiểu vê web worker thông qua sơ đồ đơn giản dưới đây:

undefined

Worker và Main script giao tiếp thông qua message. Cụ thể nếu phát đi là postMessage, và lắng nghe nhận vào là onmessage

Khởi tạo worker

Do worker được khởi tạo cần một path dẫn tới file javascript worker, mà trong nhiều trường hợp mình không tạo được file js cho nên, mình đã dùng blob để thay thế. Demo như sau: 

const workerInString = ` 
let timer;
self.onmessage = function(event) {
if (event.data.cmd == 'START') {
timer = setTimeout(() => {
this.postMessage({cmd: 'END'});
}, 2000)
}
if (event.data.cmd == 'STOP') {
clearTimeout(timer);
}}
`;
const blob = new Blob([res], {type: 'application/javascript'});
const url = window.URL.createObjectURL(blob);
const worker = new Worker(url);

Tada! Bây giờ chúng ta đã có một worker ngon lành, và chức năng nó chạy y chang như bên trong biến workerInString mình đã defined trước đó. Bây giờ chúng ta thử làm một số hàm giao tiếp giữa worker và main script nhé. ^^

const start = (exp) => { 
worker.postMessage({cmd: 'START', payload: exp})
}

const stop = () => {
worker.postMessage({cmd: 'STOP'});
}

const clearSessionLogin = () => { @DoSomething }
worker.onmessage = function(event) {
if (event.data.cmd === 'END') {
clearSessionLogin()
}

Ok, chúng ta đã thực hiện xong một worker cơ bản có thể trao đổi thông tin thông qua message rồi. Bạn có ý tưởng làm gì đó chưa? Nếu có ý tưởng hay ho với web worker có thể chia sẻ bên dưới chúng ta cùng thảo luận nhé !

Các bạn có thể xem thêm bài này của an h Lam Pham, cũng khá hay 

Tác giả
Cùng tác giả