【问题标题】:Ajax-call sync vs async?Ajax 调用同步与异步?
【发布时间】:2017-07-13 21:50:39
【问题描述】:

我遇到了一个问题,经过几个小时的搜索,当我偶然发现可以将 ajax 调用的异步选项设置为 false 时,我解决了这个问题。我的代码现在完全按照我的预期工作,但我想知道我的解决方案是否很好,或者是否可以以更好的方式解决。如果我的解决方案不好,你为什么这么认为?异步与同步,什么是最好的?是否应该始终尽可能多地使用异步调用?

var pageIndex = 0;

(function () {
   GetData();

   $(window).scroll(function () {
       if ($(window).scrollTop() ==
           $(document).height() - $(window).height()) {
           GetData();
       }
   });
})();

$.ajax({
    type: 'GET',
    url: '/Blog/GetPostsByBlogId',
    data: { "id": @Model.First().ReqBlog.Id, "pageindex": pageIndex },
    dataType: 'json',
    success: function (response) {
         DisplayData(response);
    },
    beforeSend: function () {
         $("#progress").show();
    },
    complete: function () {
         $("#progress").hide();
    },
    error: function (response) {
         alert("Error while retrieving data!");
    }
});

在成功的情况下我调用了以下函数:

function DisplayData(response)
{
     if (response != null) {
         $.each(response, function (i, post) {
              $.ajax({
                  async: false,
                  url: "/Blog/GetPostPartialView",
                  data: post,
                  type: "POST",
                  success: function (response) {
                       $("#posts-container").append(response);
                  }
               });
            });
            pageIndex++;
      }
}

如果没有“async: false”,则每次刷新时数据都会以随机顺序显示。使用“async: false”,数据每次都以正确的顺序显示。

编辑:

我使用以下解决方案来避免使用 async: false。

我的 DisplayData 函数现在看起来像这样:

function DisplayData(response)
{
     if (response != null) {
         $.each(response, function (i, post) {
             $('#posts-container').append($('<div>').load("/Blog/GetPostPartialView", { Id: post.Id, Title: post.Title, Body: post.Body, Created: post.Created, Updated: post.Updated, Views: post.Views, Blog: post.Blog, Tags: post.Tags, Comments: post.Comments, Author: post.Author }));
         });
         pageIndex++;
     }
}

【问题讨论】:

    标签: jquery ajax asynchronous


    【解决方案1】:

    async: false糟糕的做法。这是一个糟糕的解决方案,并且很少有有效的情况。事实上,这太糟糕了,如果您检查控制台,您会看到一个浏览器警告,告诉您不要使用它。

    关于您的订单被随机化的问题,这是因为循环中的AJAX请求都在不同的时间完成。要解决此问题,您应该删除 async: false 并且:

    1. 在客户端将返回的数据整理在一起,然后在显示之前手动sort()

    2. 更改您的服务器代码,以便在一次 AJAX 调用中传递所有数据,然后您可以按正确的顺序返回所有必需的信息。

    第二个选项到目前为止是更好的解决方案,因为它还可以避免由于您当前的 (N 篇博文 + 1) 请求而导致的服务器 DDOS-ing淹没它。

    【讨论】:

    • 感谢您的回复和建议的解决方案。为什么使用 async: false 不好?
    • 有几个问题,但主要是因为它阻止了浏览器的UI线程更新窗口。这使得浏览器在用户看来就像它已经崩溃和/或挂起,直到请求完成。如果请求需要一秒钟或更长时间才能完成,这对您的用户来说将非常明显。 This question有更完整的解释。
    • 感谢您的帮助。非常感激! :-)
    【解决方案2】:

    async=false 属性将导致阻塞执行 javascript 代码流,这通常是非常糟糕的做法。使用 ajax async=true 时,无法确定多个 ajax 调用的顺序。如果您无法在服务器端执行任何操作,则可以将检索到的数据收集到客户端的数据结构中,并按照您的意愿进行排序。您还可以在之前的 ajax 调用完成后调用即将到来的 ajax 调用。这样,您就可以按照发送 ajax 请求的顺序获得结果。

    【讨论】:

    • "您还可以在之前的 ajax 调用完成后调用即将到来的 ajax 调用。这样,您可以按照发送 ajax 请求的顺序获得结果。"您对我的具体情况有什么建议吗?
    • 例如,您为第一个 Id 调用“Blog/GetPostsByBlogId”,在“成功”回调中为下一个 Id 调用等。您可以使用递归 ajax 调用,例如 stackoverflow.com/questions/23355168/…。然而;这种做法会导致向您的服务器发出许多请求,因此您应该明智地使用它。
    • @RoryMcCrossan 它相似但不完全相同,因为您正在迭代 DisplayData 函数中返回的帖子并将 ajax 请求发送到“/Blog/GetPostPartialView”,而无需等待前一个完成。您应该对该函数采用相同的方法。
    • 所以你建议 OP 使用 async: false,OP 已经在使用它现在理解是糟糕的做法,应该避免......
    • 这实际上取决于您的要求。在某些情况下应该使用 async=false 但通常是个坏主意。
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    相关资源
    最近更新 更多