【问题标题】:Why does this jQuery synchronous ajax call block the UI before it has executed?为什么这个 jQuery 同步 ajax 调用在执行之前会阻塞 UI?
【发布时间】:2016-10-27 09:43:40
【问题描述】:

我对这个同步 jquery ajax 请求感到困惑。 ajax 加载程序直到 ajax 调用完成后才会显示。我很清楚同步请求会阻塞 UI,但是为什么它在该行代码被命中之前就开始阻塞呢?我一定是误解了执行顺序的基本原理。

            $("#ajax-loader").show(1, function(){
                $.ajax({
                    url: xxx,
                    type: "POST",
                    async: false,
                    success: function (data) {
                        hideAjaxLoader();
                    }
                });
            });

【问题讨论】:

  • 如果你不想阻塞 UI,它应该是异步的。只需删除 async: false 即可。
  • 因为它是同步的?!通常你不应该使用async:false
  • 您只需要注意,在执行所有当前同步代码之后,DOM 将被渲染(将显示您的加载器)。这就是为什么在请求之前没有显示加载器的原因。
  • @Liam:看到这个问题——OP 清楚地意识到了这一点。问题是为什么它会阻止加载器在理论上被称为加载器显示时显示。

标签: javascript jquery


【解决方案1】:

尽管 jQuery 在调用包含同步 ajax 调用的代码时认为动画是完整的,但这并不意味着浏览器在回调之前已经完成了渲染结果的所有工作。而且由于大多数浏览器在同步 ajax 调用期间完全阻止了他们的 UI,所以直到稍后才会处理它。

显然,只要有可能,就不要使用同步 ajax,因为它有这种阻塞 UI 的行为。

但是,如果您绝对无法避免使其同步(我从未遇到过这种情况的有效示例;我听说它们存在),请在 jQuery 认为动画是在启动 ajax 之前完成的。特别是 Firefox 似乎需要相当多的时间:

$("#ajax-loader").show(1, function(){
    setTimeout(function() {
        $.ajax({
            url: xxx,
            type: "POST",
            async: false,
            success: function (data) {
                hideAjaxLoader();
            }
        });
    }, 50); // 50 ms
});

再次,我强烈建议不要使用同步 ajax,但如果需要,只需延迟开始。

【讨论】:

  • 非常感谢,这是一个很好的解释。我错误地认为 jQuery 的“完成”概念会与浏览器匹配,但显然这就是我要出错的地方。
  • 如果有兴趣,我们在这里使用同步的原因只是半有效的。我们需要对从代码中许多地方调用的函数进行更改。要使用异步请求,需要重新处理所有调用以包含回调。这反过来又需要在发布更改之前进行大量手动测试。使请求同步意味着我们不必添加回调来进行更改,因此不必进行这些重新测试。显然,架构是这里真正的问题。
  • 很好的解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多