kingrichard2005
kingrichard2005

Reputation: 7269

Delay between repeated AJAX call to a web method

I have a ASP.Net web app with jquery implemented on the client side. within a while loop, the client side jquery script makes an asynchronous call to a web method in the server side code. The call returns the status of a long running server side task which jquery uses to update the user. The goal is to have jquery repeatedly call the server until the status is complete, once done it breaks out of the while loop and notifies the user thatthe task is complete.

My problem is that the below code runs in a while loop, but I want to make it delay or sleep between each call in order to prevent overwhelming the server with status requests. I tried calling setTimeout in the code below, but it only works with the initial ajax call, every subsequent call occurs back to back. Is there a way to efficiently delay each subsequent call to the server? Is this the most efficient way to achieve the kind of behavior I'm describing? Ideally I'd like a 2-5 second delay between each call.

I have the following code

Client Jquery:

var alertTimerId;
$('input[name=btnStatus]').click(function () {

    var result  = false;
    //Loop while server reports task complete is true
    while (!result) {
      alertTimerId = setTimeout(function () {
        $.ajax({
          type: "POST",
          url: "Default.aspx/GetStatus",
          data: "{}",
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          async: true,
          success: function (msg) {
            if(msg.d != false)
              result = msg.d;
          },
          error: function (xhr, ajaxOptions, thrownError) {
            alert('AJAX failure');
          }
        });
      }, 2000);


      if (count > 0) {
        count--;
      }
    }


  });

Server Side ASP

[System.Web.Services.WebMethod]
        public static bool GetStatus()
        {
            return result;
        }

Upvotes: 1

Views: 5224

Answers (2)

asawyer
asawyer

Reputation: 17808

Underscore.Js has a .throttle() helper function:

throttle_.throttle(function, wait)

Creates and returns a new, throttled version of the passed function, that, when invoked repeatedly, will only actually call the original function at most once per every wait milliseconds. Useful for rate-limiting events that occur faster than you can keep up with.

var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);

Upvotes: 0

nnnnnn
nnnnnn

Reputation: 150030

How about something like the following? The idea is that the Ajax call is encapsulated in a function, doAjax(), and then from within the Ajax success handler if the result is false you use setTimeout() to queue up another call to doAjax, otherwise you take whatever action you want to take for a true result. (You could optionally call doAjax() from the Ajax error handler too.)

$('input[name=btnStatus]').click(function () {

    function doAjax() {
       $.ajax({
          type: "POST",
          url: "Default.aspx/GetStatus",
          data: "{}",
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          async: true,
          success: function (msg) {
             if (!msg.d)
                 setTimeout(doAjax, 2000);
             else {
                 // Success! Notify user here
             }
          },
          error: function (xhr, ajaxOptions, thrownError) {
            alert('AJAX failure');
          }
       });
    }

    doAjax();

});

(Note: I've removed the if statement with count, since it seemed to have no relevance to the question. If your real code uses it just update it within the Ajax success handler too.)

Upvotes: 4

Related Questions