专栏首页前端之旅jQuery AJAX load()方法中代码执行顺序的问题

jQuery AJAX load()方法中代码执行顺序的问题

问题来源于菜鸟教程介绍 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 是没办法的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 深入理解this绑定

    js中的词法作用域是静态的,需要关注的往往是函数的声明位置而不是调用位置—–例如闭包引用自由变量时,应该注意闭包函数的声明位置;而this却在某种程度上类似于动...

    Chor
  • 「译」JavaScript 究竟是如何工作的?(第二部分)

    我们通常会使用这种简单有效的算法来判定可以从内存堆中安全清除的对象。算法的工作方式正如其名:将对象标记为可获得/不可获得,并将不可获得的对象清除。 垃圾回收器周...

    Chor
  • 记两道关于事件循环的题

    这里的关键其实是搞清楚 await async2() 做了什么事情。我以为在 async1 内部,async2 被调用之后,就会继续往后执行,因此是先打印 as...

    Chor
  • C语言实现链栈

    链栈是栈的链式存储结构,链栈可以用单链表的头插法实现。会单链表,链栈、链队,树,二叉树等都很好理解。

    忆想不到的晖
  • 如何将后端传的时间戳转化为年月日

    在项目里面,涉及到时间相关问题,后端一般会传一个时间戳给前端,后端传过来的时间戳如下。 data.json

    王小婷
  • 第82天:jQuery中prop()和attr()的区别

     这个例子里<a>元素的DOM属性有“href、target和class",这些属性就是<a>元素本身就带有的属性,也是W3C标准里就包含有这几个属性,或者说在...

    半指温柔乐
  • Java工程师学习指南第7部分:重新学习MySQL与Redis

    本文整理了微信公众号【Java技术江湖】发表和转载过的Mysql和Redis相关优质文章,想看到更多Java技术文章,就赶紧关注本公众号吧吧。

    Java技术江湖
  • 读书笔记-你不知道的JavaScript(上)

    本文首发在我的个人博客:http://muyunyun.cn/ 《你不知道的JavaScript》系列丛书给出了很多颠覆以往对JavaScript认知的点...

    牧云云
  • 用TextView实现富文本展示,点击断句和语音播报

    最近有一个需求:移动端需要展示用户在PC端做的笔记,而笔记内容是富文本形式——有图片,有文字,文字可以设置颜色、加粗、倾斜等等。同时,用户点击的时候能够语音朗读...

    蜻蜓队长
  • [CodeIgniter4]phpspreadsheet的使用

    https://phpspreadsheet.readthedocs.io/en/latest/

    landv

扫码关注云+社区

领取腾讯云代金券