【问题标题】:Dealing with concurrent Ajax requests处理并发的 Ajax 请求
【发布时间】:2011-11-25 00:16:28
【问题描述】:

我正在尝试执行以下操作:

  • 我有一个链接列表,每个链接在单击时执行不同的 Ajax 调用。
  • 每个 Ajax 响应都被分配了一个显示目标。
  • 在处理请求时,仍然可以单击链接(= 进一步的 Ajax 调用)。
  • 下面的示例有两个目标和四个链接:两个指向 DIV#d1,两个指向 DIV#d2。

如何确保只有对最后一个请求的响应最终会显示在其目标 DIV 中?

如果我单击标记为Data1 的链接,然后单击Data2,则必须中止第一个调用,因为 Response1 可能在 Response2 之后到达。这个问题似乎意味着我必须跟踪每个目标的先前请求,以便在发出新请求时中止它们。

我已经编写了这段代码。我想知道您是否认为这是正确的方法。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title></title>
  </head>
  <body>
    <ul>
      <li><a href="data1.htm" class="trigger" data-target="d1">Data 1</a></li>
      <li><a href="data2.htm" class="trigger" data-target="d1">Data 2</a></li>
      <li><a href="data3.htm" class="trigger" data-target="d2">Data 3</a></li>
      <li><a href="data4.htm" class="trigger" data-target="d2">Data 4</a></li>
    </ul>
    <div id="d1"></div>
    <div id="d2"></div>
    <script type="text/javascript" src="/test/jquery-1.7.1.min.js"></script>
    <script type="text/javascript">
      $(function(){
        var register = {};

        $(".trigger").on("click", function() {
          var target = $(this).attr("data-target");
          var url = $(this).attr("href");
          if (register[target] == undefined) register[target] = [];

          ajaxCall = $.get(url, function(data) { // Ajax request
            $("#" + target).html(data);
          });

          for (a in register[target]) { // Aborts existing ajax requests for this target
            register[target][a].abort();
          }
          register[target] = []; // Empty register for this target
          register[target].push(ajaxCall); // Register current ajax request

          return false;
        });

      });
    </script>
  </body>
</html>

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    在我看来,你的想法是对的。但是,您不应该使用for in 来循环数组。此外,您可能希望先中止所有呼叫(只是为了确定)。

    实际上,您在每次请求时都会清除数组,并且只用一个 ajax 调用填充它。在这种情况下,不必遍历数组,因为您知道如果数组不为空,它将只包含一个元素。另一方面,您不知道它是包含零个元素还是一个元素,因此如果存在循环,则循环是中止调用的最简洁方法。

    另外,您可以使用.data 获取data- 属性。

    最后,您可以利用|| 技巧。

    var target = $(this).data("target"),
        url = $(this).attr("href");
    
    register[target] = register[target] || [];
    
    $.each(register[target], function() {
        this.abort();
    });
    
    ajaxCall = $.get(url, function(data) { // Ajax request
        $("#" + target).html(data);
    });
    
    register[target].push(ajaxCall); // Register current ajax request
    

    【讨论】:

    • 感谢您的 cmets 和干净的代码。我仍然认为register[target] 在推入新调用之前确实应该清除每个中止的请求(这实际上与在循环后清除整个数组相同)。所以我会保留register[target] = [];
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多