Vì JavaScript chạy trong một luồng duy nhất, sau khi yêu cầu AJAX được thực hiện, điều gì thực sự xảy ra trong nền? Tôi muốn có một cái nhìn sâu sắc hơn về điều này, bất cứ ai có thể làm sáng tỏ?
Vì JavaScript chạy trong một luồng duy nhất, sau khi yêu cầu AJAX được thực hiện, điều gì thực sự xảy ra trong nền? Tôi muốn có một cái nhìn sâu sắc hơn về điều này, bất cứ ai có thể làm sáng tỏ?
Câu trả lời:
Bên dưới trang bìa, javascript có một hàng đợi sự kiện. Mỗi khi một chuỗi thực thi javascript kết thúc, nó sẽ kiểm tra xem liệu có một sự kiện nào khác trong hàng đợi để xử lý hay không. Nếu có, nó kéo nó ra khỏi hàng đợi và kích hoạt sự kiện đó (ví dụ như nhấp chuột chẳng hạn).
Mạng mã gốc nằm dưới lệnh gọi ajax sẽ biết khi nào phản hồi ajax được thực hiện và một sự kiện sẽ được thêm vào hàng đợi sự kiện javascript. Làm thế nào mã gốc biết khi nào cuộc gọi ajax được thực hiện tùy thuộc vào việc thực hiện. Nó có thể được thực hiện với các luồng hoặc nó cũng có thể là do sự kiện tự điều khiển (nó không thực sự quan trọng). Điểm quan trọng của việc triển khai là khi phản hồi ajax được thực hiện, một số mã gốc sẽ biết nó đã được thực hiện và đưa một sự kiện vào hàng đợi JS.
Nếu không có Javascript nào đang chạy vào thời điểm đó, sự kiện sẽ được kích hoạt ngay lập tức sẽ chạy trình xử lý phản hồi ajax. Nếu một cái gì đó đang chạy vào thời điểm đó, thì sự kiện sẽ được xử lý khi chuỗi thực thi javascript hiện tại kết thúc. Không cần phải có bất kỳ cuộc bỏ phiếu nào bởi công cụ javascript. Khi một đoạn Javascript kết thúc thực thi, công cụ JS chỉ kiểm tra hàng đợi sự kiện để xem liệu có gì khác cần chạy không. Nếu vậy, nó sẽ bật sự kiện tiếp theo ra khỏi hàng đợi và thực thi nó (gọi một hoặc nhiều hàm gọi lại được đăng ký cho sự kiện đó). Nếu không có gì trong hàng đợi sự kiện, thì trình thông dịch JS có thời gian rảnh (bộ sưu tập rác hoặc không hoạt động) cho đến khi một số tác nhân bên ngoài đặt một thứ khác vào hàng đợi sự kiện và đánh thức lại nó.
Bởi vì tất cả các sự kiện bên ngoài đều đi qua hàng đợi sự kiện và không có sự kiện nào được kích hoạt trong khi javascript thực sự đang chạy một thứ khác, nên nó vẫn duy trì một luồng.
Dưới đây là một số bài viết về các chi tiết:
.focus()
một mục và điều đó sẽ kích hoạt một vài sự kiện khác, chẳng hạn như sự kiện "làm mờ" trên mục đó với trọng tâm. Sự kiện mờ đó xảy ra đồng bộ và không đi qua hàng đợi sự kiện nên nó sẽ xảy ra ngay trước những thứ khác có thể có trong hàng đợi sự kiện. Trong thực tế, tôi chưa bao giờ thấy điều này là một mối quan tâm thực tế.
Bạn có thể tìm thấy ở đây một tài liệu rất đầy đủ về xử lý các sự kiện trong javascript.
Nó được viết bởi một anh chàng làm việc về việc triển khai javascript trong Opera Browser.
Chính xác hơn, hãy xem các tiêu đề: "Dòng sự kiện", "Hàng đợi sự kiện" và "Sự kiện không dành cho người dùng": bạn sẽ biết rằng:
Lưu ý: Liên kết ban đầu là: liên kết , nhưng hiện đã chết.
Tôi muốn giải thích một chút, liên quan đến việc thực hiện ajax được đề cập trong câu trả lời.
Mặc dù thực thi Javascript (thông thường) không đa luồng - như đã lưu ý trong các câu trả lời ở trên - tuy nhiên , việc xử lý thực sự AJAX responses
(cũng như xử lý yêu cầu) không phải là Javascript và thông thường - là - đa luồng. (xem triển khai nguồn crom của XMLHttpRequest mà chúng tôi sẽ thảo luận ở trên)
và tôi sẽ giải thích, hãy lấy đoạn mã sau:
var xhr = new XMLHttpRequest();
var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );
xhr.onload = function( e ) {
console.log(t() + ': step 3');
alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');
after an AJAX request is made
(- sau bước 1), sau đó trong khi mã js của bạn tiến hành thực thi (bước 2 và sau đó), trình duyệt bắt đầu công việc thực sự của: 1. định dạng yêu cầu tcp 2. mở ổ cắm 3. gửi tiêu đề 4. bắt tay 5. gửi cơ thể 6. phản hồi chờ đợi 7. đọc tiêu đề 8. đọc cơ thể, vv tất cả việc thực hiện này thường được chạy trong một luồng khác song song với thực thi mã js của bạn. ví dụ, việc triển khai crom được đề cập sử dụng Trình tải có thể chuyển đổi đi vào, (bạn cũng có thể có một số ấn tượng bằng cách xem tab mạng của tải trang, bạn sẽ thấy một số yêu cầu đồng thời).
để kết luận, tôi sẽ nói rằng - ít nhất - hầu hết các hoạt động I / O của bạn có thể được thực hiện đồng thời / không đồng bộ (và bạn có thể tận dụng lợi thế này bằng cách chờ đợi chẳng hạn). nhưng tất cả các tương tác với các hoạt động đó (việc phát hành, thực hiện gọi lại js) đều đồng bộ.