【问题标题】:Wait unitl ajax and its callback function finish等到ajax及其回调函数完成
【发布时间】:2013-09-16 02:44:37
【问题描述】:

我正在构建一个允许用户同时执行多个操作的网络应用程序。例如,用户可以打开列表、删除列表或添加新列表。

每个动作都会进行一次 ajax 调用并执行回调函数以在成功时更新 UI。我想确保这些操作以序列化的方式执行,这样 UI 就不会不同步。例如,如果用户打开一个列表,但在几分之一秒后删除了该列表,这取决于哪个 ajax 调用先完成,它可能会显示现在应该删除的列表。

为了实现这一点,对于每个操作,我想等到 ajax 调用它的回调函数完成。我怎样才能做到这一点?

【问题讨论】:

  • 如何在回调函数启动时禁用 UI 元素,并在回调完成时重新启用它们?正如 N1ck 在下面指出的那样,.always 处理程序将是重新启用您的 UI 元素的地方。
  • 但是,如果我有多个同时进行的 ajax 调用将无法正常工作。
  • 啊,所以你想要顺序控制。我可以提出一个替代方案并建议您不要这样做吗?这样的系统有很多方法可以解决问题。如果用户在瞬间启动操作 A 和 B,但 A 导致错误怎么办?如果服务器在 A 之前收到对 B 的请求怎么办?为什么不建立一个更健壮的客户端状态呢?以您的示例为例,当用户单击“删除”时,让客户端状态立即删除该项目。如果客户端随后收到“查看”该项目的命令,它会拒绝。
  • 是的,我想要一个序列控制。我懂了。但是,如果用户删除了一个项目,但请求在服务器端失败(例如,由于某些约束违反)怎么办?然后,该列表在客户端被删除,即使它实际上不是。
  • 在这种情况下,客户端对删除回调的响应可能是取消删除项目的错误处理程序。假设这是一种通常不会失败的删除操作,这可以让您的应用程序看起来真的快,因为该项目会立即从用户视图中删除。

标签: javascript ajax


【解决方案1】:

如果您使用 jQuery,则在 .done()/.fail() 之后调用 .always() 回调。

$.ajax("example.php")
    .done(function() {
        alert("success");
    })
    .fail(function() {
        alert("error");
    })
    .always(function() {
        alert("complete"); //Called after done/fail callbacks
    });

【讨论】:

  • 这可能不是我想要的。我知道我可以使用.always(),但我仍然不知道ajax 调用何时结束。对于每个操作,我需要 1) 执行 ajax 调用,以及 2) 执行回调。然后,我将继续处理下一个动作。
  • 你的初始回调是done()或者fail(),也就是ajax调用结束的时候,然后在这些回调之后调用.always()。您可以有一个布尔值来表示它当前是否正在执行 ajax 调用,并防止采取其他操作,但这似乎完全违背了使用 ajax 的目的。
  • 如果我同时有多个 ajax 调用,我不能只使用布尔值,因为一个调用可能会在其他 ajax 调用正在进行时将其设置为 false。我可以使用$.ajaxStart$.ajaxStop(),但是我不知道回调何时结束。我想它确实破坏了 ajax 调用的目的,但我试图使 UI 更新同步。有什么建议吗?
  • ".. 取决于哪个 ajax 调用首先完成,它可能会显示应该现在删除的列表。"我认为您只需要重新考虑在进行 ajax 调用后如何获取更新的列表,如果他们从不同的浏览器/选项卡中删除某些内容怎么办?如果上面的建议没有回答问题,我认为您正在寻找错误的领域来解决这个问题。
【解决方案2】:

使用 Jquery,您可以将 async: false 添加到您的 Ajax 调用或使用 Jquery deferred 以确保仅在 Ajax 调用完成后才发出操作(假设您使用 Jquery)。

如果您有多个 Ajax 请求,示例可能如下所示:

$.ajax({url: url}).pipe(function() {
  // some ajax stuff
  return $.ajax({});
}).pipe(function() {
  // some more ajax stuff (3rd request)
  return $.ajax({});
}).done(function() {
  // done with all ajax requests...
});

【讨论】:

  • 是的。此响应(和问题)不考虑错误处理。
猜你喜欢
  • 1970-01-01
  • 2019-05-11
  • 2017-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多