0

I've reviewed many of the discussion here on how to write ajax calls using deferred. Somehow I just am not getting what I need to do. I've simplified my code here for example purposes. Basically I have a form with some buttons. Clicking them sometimes sets off an ajax call to log data on my server. (Sometimes it initiates several calls)

The problem is that on occasion my PHP code executes a second call before the first call is finished. So I know I need to wait until I get a response from call #1 before I issue call #2. I have a lot of buttons and combinations in which the ajax calls could be made. A huge nested block is not feasible.

So I guess I need to use the .Deferred() object. I'm just not sure how to set it up. All the previous Stackoverflow responses don't seem like they apply to my situation where the call to my ajax function could come from a variety of different places.

I just want an internal queue that just waits until one ajax call finishes before executing the next.

Here is my code:

<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>

The basic problem is that if I click #btn1 and #btn2 in rapid succession, I want my code to wait for a response from #btn1 until it sends the ajax call for #btn2.

ok, I've updated my code and it almost works. The first two clicks work great. But it gets tripped up on the third click. Looks like previousPromise gets returned as an object instead of true/false. How do I make it return a boolean?

<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>
Thread7
  • 1,081
  • 2
  • 14
  • 28

1 Answers1

-1

I think you need async: false for not to execute your second request before first one completes.

$.ajax({
    method: "GET", 
    url: url, 
    data: param,
    async: false,   <--- Add this and try again.
});   
H45H
  • 1,019
  • 10
  • 28
  • This is probably the best solution I've come across. It works perfectly. The only problem is that this feature of async: false is deprecated. I think the "correct" way to do it would be to get my second set of code above to work. But so far, no luck. – Thread7 May 14 '19 at 16:20