20 điểm bởi GN⁺ 2024-11-13 | Chưa có bình luận nào. | Chia sẻ qua WhatsApp
  • Web Locks API cho phép lấy khóa một cách bất đồng bộ trong một tab hoặc web worker, thực hiện công việc rồi giải phóng khóa
  • Trong khi khóa đang được giữ, các script khác trong cùng origin không thể lấy cùng khóa đó, nhờ vậy có thể điều phối tài nguyên an toàn giữa nhiều tab hoặc worker
  • Chỉ dùng được trong Secure Context(HTTPS) và có thể sử dụng trong Web Workers

Khái niệm chính và cách sử dụng

  • Khóa(Lock) là một tài nguyên trừu tượng được nhận diện bằng tên do ứng dụng web định nghĩa
  • Ví dụ, khi đồng bộ IndexedDB và mạng trên nhiều tab, có thể dùng khóa “my_net_db_sync” để chỉ cho phép một tab thực hiện đồng bộ tại một thời điểm
  • Luồng sử dụng:
    1. Yêu cầu khóa
    2. Thực hiện tác vụ bất đồng bộ
    3. Tự động giải phóng khóa sau khi công việc hoàn tất

Mã ví dụ

navigator.locks.request("my_resource", async (lock) => {
await do_something();
await do_something_else();
});

  • Trong khi khóa đang được giữ, các yêu cầu khác cho cùng khóa sẽ được đưa vào hàng đợi, và khi khóa được giải phóng thì yêu cầu đầu tiên sẽ được xử lý

Tùy chọn

  • mode: chế độ mặc định là “exclusive”(độc quyền), cũng có thể dùng chế độ “shared”(chia sẻ). “exclusive” chỉ cho phép một yêu cầu, còn “shared” có thể cho phép nhiều yêu cầu
  • ifAvailable: nếu không thể lấy khóa ngay lập tức thì yêu cầu thất bại, callback trả về null
  • steal: giải phóng khóa hiện có cùng tên và ưu tiên xử lý yêu cầu mới
  • signal: có thể hủy yêu cầu thông qua AbortSignal (ví dụ: triển khai timeout)

Giám sát

  • có thể dùng navigator.locks.query() để xem trạng thái khóa hiện tại của origin
  • Điều này hữu ích khi debug, giúp kiểm tra khóa nào đang được giữ và những khóa nào đã được yêu cầu

Cách dùng nâng cao

  • Để điều khiển rõ ràng thời điểm hoàn tất của tác vụ bất đồng bộ, có thể trả về một Promise

let resolve;
const p = new Promise((res) => { resolve = res });

navigator.locks.request("my_resource", (lock) => p);

  • Khóa sẽ được giải phóng khi gọi resolve()

Tránh deadlock

  • Deadlock là tình huống các yêu cầu khác nhau xung đột về thứ tự nên không thể tiếp tục
  • Ví dụ, nếu tab 1 đang giữ khóa A và tab 2 đang giữ khóa B, rồi tab 1 yêu cầu khóa B trong khi tab 2 yêu cầu khóa A thì cả hai sẽ phải chờ nhau
  • Để tránh điều này:
  • Không lồng các yêu cầu khóa
  • Thực hiện yêu cầu khóa theo đúng thứ tự
  • Đặt timeout để hủy yêu cầu

Giao diện

  • Lock: cung cấp tên và chế độ của khóa được yêu cầu
  • LockManager: cung cấp các phương thức để yêu cầu khóa mới hoặc truy vấn khóa hiện có
  • Có thể lấy instance qua navigator.locks
  • WorkerNavigator.locks có thể dùng trong Web Workers

Đặc tả và hỗ trợ trình duyệt

  • Đặc tả: Web Locks API
  • Tương thích trình duyệt: chỉ được hỗ trợ trên một số trình duyệt; có thể kiểm tra tình trạng hỗ trợ trên các trình duyệt mới nhất tại MDN

Ý kiến của GN⁺

  • Web Locks API hữu ích để giải quyết các vấn đề đồng bộ tài nguyên trong môi trường bất đồng bộ
  • Vì có khả năng xảy ra deadlock nên cần cẩn trọng khi sử dụng, và nên cân nhắc các cơ chế an toàn như đặt timeout
  • Shared mode có thể cải thiện hiệu năng cho các tác vụ chỉ đọc, nhưng vẫn cần xem xét kỹ các race condition
  • API này có thể được dùng như một giải pháp thay thế để xử lý các vấn đề đồng bộ vốn có của localStorage hoặc IndexedDB

Chưa có bình luận nào.

Chưa có bình luận nào.