如何为Ajax调用设置Jquery Deferred

时间:2019-05-13 19:34:25

标签: javascript jquery ajax

我已经回顾了许多有关如何使用deferred编写ajax调用的讨论。不知何故我只是没有得到我需要做的。我在这里出于示例目的简化了代码。基本上我有一个带有一些按钮的表格。单击它们有时会引发ajax调用,以将数据记录到我的服务器上。 (有时会发起多个呼叫)

问题在于,有时我的PHP代码会在第一个调用完成之前执行第二个调用。所以我知道我需要等到我收到第1个呼叫的响应后才能发出第2个呼叫。我有很多可以进行ajax调用的按钮和组合。巨大的嵌套块是不可行的。

所以我想我需要使用.Deferred()对象。我只是不确定如何设置。以前的所有Stackoverflow响应似乎都不适用于我的情况,在这种情况下,对Ajax函数的调用可能来自多个不同的地方。

我只想要一个内部队列,等待一个ajax调用完成之后再执行下一个。

这是我的代码:

<html>
<head>
  <script src="jquery.min.js?x=1"></script>
</head>
<body>
<button type="button" id="btn1">Send Ajax 1</button>
<button type="button" id="btn2">Send Ajax 2</button>
<script>
  $("#btn1").click(function(){ send_ajax(1); });
  $("#btn2").click(function(){ send_ajax(2); }); 
  function send_ajax(val){
     var param="param="+val;
    var url = 'save_some_data.php';
    $.ajax({method: "GET", url: url, data: param});   
  }
</script>
</body>
</html>

基本问题是,如果我快速依次单击#btn1和#btn2,我希望我的代码等待#btn1的响应,直到它发送对#btn2的ajax调用。 < / p>

好的,我已经更新了代码,它几乎可以正常工作。前两次单击效果很好。但是在第三次点击时它就被绊倒了。看起来previousPromise被作为对象而不是true / false返回。如何使其返回布尔值?

<html>
<head>
  <script src="jquery.min.js?x=1"></script>
</head>
<body>
<button type="button" id="btn1">Send Ajax 1</button>
<button type="button" id="btn2">Send Ajax 2</button>
<script>
var previousPromise=false;
  $("#btn1").click(function(){ handler(1); });
  $("#btn2").click(function(){ handler(2); }); 
  function handler(val){
      if (previousPromise) {
        // Even if the previous request has finished, this will work.
        previousPromise = previousPromise.then(function () {
          return actualSender(val);
        });
        return previousPromise;
      }

      // first time
      previousPromise = actualSender(val);
      return previousPromise;     
  }
  function actualSender(val){
     var param="param="+val;
    var url = 'save_data.php';
    return($.ajax({method: "GET", url: url, data: param}));
  }
</script>
</body>
</html>

1 个答案:

答案 0 :(得分:-1)

我认为您需要 async:false ,以便在第一个请求完成之前不执行第二个请求。

$.ajax({
    method: "GET", 
    url: url, 
    data: param,
    async: false,   <--- Add this and try again.
});