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 是没办法的。