jQuery AJAX load()方法中程式碼執行順序的問題

  • 2019 年 11 月 8 日
  • 筆記

問題來源於菜鳥教程介紹 jQuery load() 方法時用的一個實例: JS:

$("button").click(function(){    $("#div1").load("demo_test.txt",function(responseTxt,statusTxt,xhr){      if(statusTxt=="success")        alert("外部內容載入成功!");      if(statusTxt=="error")        alert("Error: "+xhr.status+": "+xhr.statusText);    });  });

HTML:

<div id="div1"><h2>使用 jQuery AJAX 修改該文本</h2></div>  <button>獲取外部內容</button>

這裡作為load方法參數的函數是一個回調函數。什麼是回調函數呢?我們先來看看回調的英文定義:

A callback is a function that is passed as an argument to another function and is executed after its parent function has completed。

字面上的理解,回調函數就是一個參數,將這個函數作為參數傳到另一個函數裡面,當那個函數執行完之後,再執行傳進去的這個函數。這個過程就叫做回調。那麼根據這個解釋,這段程式碼應該是先執行 load("demo_test.txt") 載入外部內容,之後再執行回調函數彈出 alert。但是實際運行後發現和預想的不一樣:

方法中程式碼執行順序的問題-1.png) 方法中程式碼執行順序的問題-2.png)

從結果來看,是先彈出 alert 再改變文本內容。那麼,為什麼會這樣呢?難道上面的說法有誤?為了進一步驗證,修改程式碼如下:

$("#div1").load("demo_test.txt",function(responseTxt,statusTxt,xhr){  alert(responseTxt);  if(statusTxt=="success"){

運行:

方法中程式碼執行順序的問題-3.png) 很明顯文本內容已經改變,說明前面關於回調函數最後執行的說法是沒問題的。接著猜想,之所以先彈出 alert 再改變文本內容,可能是因為必須等回調函數執行完後才能把文本渲染到瀏覽器上。 為了進一步驗證,修改程式碼如下:

$("#div1").load("demo_test.txt",function(responseTxt,statusTxt,xhr){      if(statusTxt=="success"){            debugger;             console.log("1");        }

運行:

方法中程式碼執行順序的問題-4.png) 控制台中沒有列印出1,且程式中斷,說明此時回調函數還在執行當中,但是文本內容卻已經改變了。這說明上面的猜想錯誤—–即文本渲染到瀏覽器上不需要等到回調函數執行結束。 但是,那只是一般情況!!問題就在於,alert是可以阻塞瀏覽器的渲染工作的!

重新運行最初的程式碼,可以看到還是先彈出 alert,文本沒變,但是這時候點開控制台的 elements,可以看到圖中紅框顯示這時候文本的內容其實已經改變了。

方法中程式碼執行順序的問題-5.png) 雖然文本內容看上去不變——但是實際情況是文本內容已經改變了,也就是 load() 方法已經生效了,只是 alert 阻塞了瀏覽器將它渲染出來。 在這裡還要注意,alert 可以阻塞瀏覽器的渲染,而 debugger 是沒辦法的。