zoukankan      html  css  js  c++  java
  • jQuery同步Ajax带来的UI线程阻塞问题

    一、需求

    在调ajax接口的时候因为有时间延迟,想要做一个loading加载的效果,等数据返回时再把loading的效果去掉。

    所以我在调ajax的代码块前面加了显示loading效果的代码,ajax结束返回之后加了隐藏loading效果的代码。然后都没有起作用。

    二、遇到问题

    在ajax请求前后,对页面的样式进行操作不起效果。

    浏览器的渲染(UI)线程和js线程是互斥的,在执行js耗时操作时,页面渲染会被阻塞掉。当我们执行异步ajax的时候没有问题,但当设置为同步请求时,其他的动作(ajax函数后面的代码,还有渲染线程)都会停止下来。即使我的DOM操作语句是在发起请求的前一句,这个同步请求也会“迅速”将UI线程阻塞,不给它执行的时间。这就是代码失效的原因。

    三、解决方法

    详细参考:https://www.cnblogs.com/lvdabao/p/3744030.html,作者和我遇到的问题完全一致

    1.我们在bxcommmon里面封装的ajaxRequest,默认ajax是同步,第一步要先将ajaxRequest设置为异步(最后一个参数设置为true)

      AjaxCommunicator.ajaxRequest(url, "POST", paramJsonObj, callback,true);

    2.引入deferred对象

      jQuery的deferred对象详解: http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

    3. 引入$.when()函数

      JQuery when(deferreds)方法 的使用:https://www.cnblogs.com/lvjiaqin/p/6814052.html

    贴一下解决代码:

    总之,想让ajax走完再加载页面,就要使用同步。但是只要同步,ajax就会阻塞ui线程,使得loading显示不出来。

    只有使用了deffer对象和$.when(),既可以ajax设为异步,保证了loading的正常显示,又可以保证在ajax走完再加载页面。因为$.when().done()会在deffer.resolve()之前的代码全部走完后才走done中的代码。

    $.when()函数只接受defferred对象,所以我们在处理ajax的函数中需要先创建defferred对象,再return就解决了。defer.resolve(ret)用于控制ajax何时结束,比如我执行完赋值操作结束ajax,进入$.when().done()中的回调函数,它还可以把数据也带出来使用。类似的,还存在一个deferred.reject()方法,作用是将dtd对象的执行状态从"未完成"改为"已失败",从而触发$.when().fail()方法。

  • 相关阅读:
    React + Webpack搭建环境
    iOS 中block中使用了外部变量的分析
    研究Extension和Category的一个例子
    43. Multiply Strings
    安装cocoapods
    iOS推送流程
    iOS中富文本NSMutableAttributedString的用法
    用杯赛尔曲线(做动画和绘图)
    字符串转换为长整型 strtol
    使用DirectUI
  • 原文地址:https://www.cnblogs.com/evaxtt/p/9585628.html
Copyright © 2011-2022 走看看