UnderstandJavaScript - Asynchronous CallBacks
Mình đã nói rất nhiều lần rằng Javascript luôn chạy đồng bộ nhưng có một vấn đề rất lớn mà mọi người hay thắc mắc đó là AsyncCallBacks , nhiều người đã từng sử dụng hoặc nghe về khái niệm này .
AsyncChronous
Như các bạn đã biết JS là đồng bộ nó không chạy bất đồng bộ nó luôn luôn chỉ thực hiện một dòng tại một thời điểm tuy nhiên trong thực tế khi phát triển ứng dụng chúng ta cần thực thi những tác vụ liên quan đến mạng , hệ điều hành như đọc ghi file và lúc đó bạn sẽ truyền một callback để khi nào tác vụ chạy xong bạn sẽ truyền data cho callback rồi invoked callback..Vậy thực tế thì JS xử lý các sự kiện bất đồng bộ này như thế nào ?
Trước hết bạn cần hiểu về JSE (The Javascript Engine)
=> Khi chúng tôi nói về việc chạy JavaScript và bản thân JSE . Ví dụ như trong một trình duyệt Internet có các yếu tố khác có các công cụ khác gọi chung là WebAPIs và các chương trình khác đang chạy chứ không phải chỉ một mình JavaScript Engine ví dụ như công cụ Rendering Engine (dùng để render ra giao diện) hay Http Request(dùng để gửi request đến server) , những thành phần này bản thân nó tách biệt với JavaScript Engine , JavaScript có các móc nối hay nói dễ hiểu hơn là có sự liên kết để nó có thể làm việc với các công cụ này , bạn có thể thắc mắc rằng tại sao JSE phải liên kết với các công cụ này ??? Bởi vì JSE không thể gửi request đến server hay render ra giao diện được ,Javascript không cung cấp những chức năng này mà phải nhờ một chương trình khác làm giúp , đây là điều đầu tiên bạn cần nhớ .
=> Khi bạn chạy một chương trình hay chạy một tác vụ , ví dụ như click vào button để show dữ liệu ra màn hình chẳng hạn , như vậy JSE sẽ làm việc với Http Request để gửi request và dùng Rendering Engine để show dữ liệu ra giao diện nhưng bạn nên nhớ rằng JSE chạy đồng bộ nhưng không có nghĩa rằng Rendering Engine hay HttpRequest này nó cũng chạy đồng bộ , hiểu đơn giản hơn thì khi bạn thực hiện một hành động mà JSE không xử lý được mà phải nhờ đến WebAPIs thì gọi đến WebAPIs (nhờ nó httpRequest gửi request đi chẳng hạn) thực hiện hành động này lúc này cần một khoảng thời gian nhất định để lấy được kết quả của hành động này và trong thời gian đó JSE vẫn tiếp tục chạy chương trình.
Execution Context Stack và Event Quee
- Chúng ta đã học về Execution Context Stack và chúng ta đã biết rằng khi một hàm được gọi sẽ tạo ra một Execution Context của riêng nó và được đẩy lên trên cùng của Execution Context Stack để thực thi.
- Hàm nào được gọi cuối cùng sẽ được đẩy lên trên cùng của Execution Context Stack (đây là cơ chết của Stack được gọi là last-in-first-out hiểu đơn giản là vào sau ra trước), một điểm bạn cần chú ý rằng chỉ có Execution Context ở trên cùng của ECS mới được thực thi mà thôi , điều này cũng phù hợp với tính chất của JavaScript là đồng bộ và đơn luồng chỉ thực thi một hành động ở một thời điểm.
- Khi một hàm được thực thi xong nó sẽ bị đẩy ra khỏi ECS để cho EC ngay dưới nó được thực thi , cứ thế cho đến khi Global Execution Context được thực thi xong và Execution Context Stack trống hoàn toàn.
=> Đây là kiến thức ở những bài trước , nhưng đây là khi bạn chạy một chương trình không có những tác vụ bất đồng bộ , vậy khi chạy những đoạn code bất đồng bộ thì JavaScript sẽ xử lý như thế nào với cơ chế đồng bộ của nó ? Đây là lúc Event Loop và Callback Queue xuất hiện Event Queue nằm bên trong JavaScript Engine , Event Queue có cơ chế khác với Stack là vào trước sẽ ra trước.
Event Lopp và CallbackQueue
Event loop : Nó có nhiệm vụ theo dõi tình trạng và ECS và CallbackQueue
CallbackQueue : một dạng cấu trúc dữ liệu với cơ chế First-In-First-Out
Ví dụ khi bạn gửi muốn đọc một file trên server , JSE sẽ bảo với thằng HttpRequest gửi request đi , server sẽ mất một khoảng thời gian để đọc file , trong khoảng thời gian nay chương trình vẫn chạy bình thường , khi server xử lý xong và gửi data về sẽ được đẩy vào làm tham số mặc định cho callback., callback này không được invoked ngay mà bị đẩy vào bên trong CallbackQueue.
=> Event Loop quan sát cho đến khi ECS trống thì nó sẽ đẩy callback vào trong ECS để nó xử lý
.
=> Bạn chú ý rằng chỉ khi ECS trống thì các callback trong Callback Queue mới được thực thi nhé.

Nhận xét
Đăng nhận xét