簡體   English   中英

JavaScript 如何在后台處理 AJAX 響應?

[英]How does JavaScript handle AJAX responses in the background?

由於 JavaScript 在單線程中運行,因此在發出 AJAX 請求后,后台實際發生了什么? 我想對此有更深入的了解,有人可以解釋一下嗎?

在幕后,javascript 有一個事件隊列。 每次執行的 javascript 線程完成時,它都會檢查隊列中是否還有另一個事件要處理。 如果有,它會將其從隊列中拉出並觸發該事件(例如鼠標單擊)。

位於 ajax 調用下的本機代碼網絡將知道 ajax 響應何時完成,並且一個事件將被添加到 javascript 事件隊列中。 本機代碼如何知道 ajax 調用何時完成取決於實現。 它可能是用線程實現的,也可能是事件驅動本身(這並不重要)。 實現的重點是當ajax響應完成時,一些本機代碼會知道它已經完成並將一個事件放入JS隊列。

如果當時沒有 Javascript 正在運行,將立即觸發該事件,該事件將運行 ajax 響應處理程序。 如果當時正在運行某些東西,那么當當前的 javascript 執行線程完成時,將處理該事件。 javascript 引擎不需要進行任何輪詢。 當一段 Javascript 完成執行時,JS 引擎只會檢查事件隊列,看看是否還有其他需要運行的東西。 如果是,它會從隊列中彈出下一個事件並執行它(調用為該事件注冊的一個或多個回調函數)。 如果事件隊列中沒有任何內容,則 JS 解釋器有空閑時間(垃圾收集或空閑),直到某個外部代理將其他內容放入事件隊列並再次喚醒它。

因為所有外部事件都通過事件隊列,並且當 javascript 實際運行其他東西時不會觸發任何事件,所以它保持單線程。

這里有一些關於細節的文章:

您可以在此處找到有關 javascript 中事件處理的非常完整的文檔。
它是由一個在 Opera 瀏覽器中處理 javascript 實現的人編寫的。

更准確地說,查看標題:“事件流”、“事件隊列”和“非用戶事件”:您將了解到:

  1. 對於每個瀏覽器選項卡或窗口,Javascript 在單個線程中運行。
  2. 事件排隊並按順序執行。
  3. XMLHttpRequest 由實現運行,回調使用事件隊列運行。

注意:原始鏈接是: link ,但現在已失效。

我想詳細說明一下,關於答案中提到的 ajax 實現。

盡管(常規)Javascript 執行不是多線程的——如上述答案中所述——但是AJAX responses的真正處理(以及請求處理)不是Javascript,而且它——通常——多線程的. (請參閱我們將在上面討論的 XMLHttpRequest 的鉻源實現

我會解釋一下,讓我們使用以下代碼:

 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后(- 在第 1 步之后),當您的 js 代碼繼續執行(第 2 步及之后)時,瀏覽器將開始以下實際工作: 1. 格式化 tcp 請求 2. 打開套接字 3. 發送標頭4. 握手 5. 發送正文 6. 等待響應 7. 讀取標頭 8. 讀取正文等 所有這些實現通常在不同的線程中運行,與您的 js 代碼執行並行。 例如,提到的chromium實現使用Threadable Loader go digg-into 😉,(您也可以通過查看頁面加載的網絡選項卡獲得一些印象,您會看到一些並發請求)。

總之,我會說 - 至少 - 您的大部分 I/O 操作可以同時/異步進行(例如,您可以使用await來利用這一點)。 但是與這些操作的所有交互(發布、js 回調執行)都是同步的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM