【问题标题】:Prior statements not getting executed on sync ajax call在同步 ajax 调用上未执行先前的语句
【发布时间】:2016-06-03 01:44:19
【问题描述】:

我有一个类似的功能

function m1(){
    $('.loader').show();

   var xargs={
          type : 'POST',
          url : resourceUrls["listUrl"],
          data : "sId="+sId,
          async:false,
          dataType : "text",
          success : OnGetJsonCallback,
          failure : function(response) {
                 $(".loader").hide();
                 }

   };

  $.ajax(xargs);
}

这里的问题是,加载程序在进行 ajax 调用之前没有显示出来。如果我放置一个正在记录的控制台日志语句。

我进行了一些搜索并了解到同步 AJAX 调用会冻结浏览器。但是它可以显示加载器然后冻结浏览器不是吗?

【问题讨论】:

  • 不要使用同步 ajax 调用!!
  • 不幸的是,我在这里需要它。
  • 为什么需要使用同步而不是异步?
  • .show() 是一个异步函数。同步 ajax(矛盾修饰法)在其结束之前阻止它。
  • 正如@nordyguy 指出的那样,我只是好奇你为什么需要同步呼叫?如果您告诉我们,我们可以建议您避免使用它。

标签: javascript jquery html ajax


【解决方案1】:

我做了一些搜索,了解到同步 AJAX 调用 冻结浏览器。但它可以显示加载器,然后冻结 浏览器不行吗?

我不同意这样做,但您可以收听完整的节目,然后进行同步呼叫:

$('.loader').show(500, m1);

function m1(){
   var xargs={
          type : 'POST',
          url : resourceUrls["listUrl"],
          data : "sId="+sId,
          async:false,
          dataType : "text",
          success : OnGetJsonCallback,
          failure : function(response) {
                 $(".loader").hide();
                 }

   };

  $.ajax(xargs);
}

【讨论】:

  • 不,一旦显示完成就会调用它 api.jquery.com/show 。此构造函数需要持续时间,并且一旦显示完成就会触发回调函数。
【解决方案2】:

主线程上的同步 XMLHttpRequest 已被弃用,因为它会对最终用户的体验产生不利影响。如需更多帮助,请查看Specs

因此,您可以通过在网页中实现 UI 拦截器,使用异步请求来获得相同的结果,而不是使用同步请求。只需将一个全宽和全高的 div 放在更高的 z-index 处。而且它不会冻结你的加载元素。

【讨论】:

    【解决方案3】:

    Javascript 是单线程的,这意味着如果调用堆栈上有任何内容,浏览器将无法调用绘制(并渲染加载器的移动),因为渲染队列正在等待堆栈清理,因此加载器不会仅在请求完成并弹出调用堆栈后才移动。

    javascript 的本质是异步的,因为您不应该为了能够响应用户交互而阻塞堆栈,这就是使用回调和异步方法的原因。

    1. 我建议你想办法使用异步而不是同步请求。 (你不能被要求在 javascript 中做这样的事情)。

    2. 如果确实如此,您可以显示一个带有静态加载文本的白屏。但是,由于下一个渲染刻度被阻止,屏幕将不会设置动画或允许用户交互。 (仅在同步请求完成之前)。

    为此,您必须编写以下内容:

    function m1(){
        $('.loader').show();
    
       var xargs={
              type : 'POST',
              url : resourceUrls["listUrl"],
              data : "sId="+sId,
              async:false,
              dataType : "text",
              success : OnGetJsonCallback,
              failure : function(response) {
                     $(".loader").hide();
                     }
    
       };
       setTimeout(function() {
          $.ajax(xargs);
       },0);
    }
    

    在超时中包装同步 ajax 请求的原因是允许浏览器在将请求放入堆栈并阻止所有内容之前进行绘制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      • 2015-02-27
      • 1970-01-01
      • 2016-04-16
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多