Giới Thiệu
queueMicrotask là API trình duyệt mới có thể dùng để chuyển mã đồng bộ thành bất đồng bộ (async):
queueMicrotask(() => { console.log('hey i am executed asychronously by queueMicrotask'); });Nó tương tự như việc chúng ta dùng setTimeout:
setTimeout(() => { console.log('hey i am executed asychronously by setTimeout'); }, 0);Vậy queueMicrotask có ích gì khi đã có setTimeout?
queueMicrotask thêm hàm (task) vào một hàng đợi và mỗi hàm được thực thi lần lượt (FIFO) sau khi task hiện tại hoàn thành công việc và khi không có mã nào khác chờ chạy trước khi quyền điều khiển ngữ cảnh thực thi được trả về cho vòng lặp sự kiện (event loop) của trình duyệt.
Về cơ bản, task của queueMicrotask được thực thi ngay sau khi call stack hiện tại rỗng trước khi chuyển quyền điều khiển cho event loop.
Trong trường hợp setTimeout, mỗi task được thực thi từ hàng đợi sự kiện, sau khi quyền điều khiển được trao cho event loop.
Vì vậy nếu thực thi setTimeout trước rồi queueMicrotask, cái nào sẽ được gọi trước? Thực thi mã dưới và tự kiểm tra:
setTimeout(() => { console.log('hey i am executed asychronously by setTimeout'); },0); queueMicrotask(() => { console.log('hey i am executed asychronously by queueMicrotask'); }); Node.js làm điều tương tự với "process.nextTick".
Khi Nào Nên Dùng Nó
Không có quy tắc cứng nhắc khi nào dùng queueMicrotask, nhưng có thể dùng khéo léo để chạy một đoạn mã mà không dừng thực thi hiện tại.
Ví dụ, giả sử chúng ta có mảng để duy trì danh sách giá trị. Sau mỗi lần chèn giá trị, chúng ta sắp xếp mảng để tìm kiếm giá trị nhanh hơn.
var arr=[]; function add(value){ arr.push(value); arr.sort(); }Tuy nhiên, tìm kiếm phần tử được thực hiện khi ai đó dùng ô tìm kiếm. Điều này nghĩa là event handler sẽ được gọi sau khi quyền điều khiển chuyển cho event loop, nên việc sắp xếp dữ liệu chặn thực thi mã đồng bộ quan trọng khác.
Đây là cách dùng queueMicrotask để cải thiện mã:
var arr = []; function add(value) { arr.push(value); queueMicrotask(() => { arr.sort(); }) }Tham Khảo
- https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask