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