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 是沒辦法的。