Search code examples
jqueryajaxabort

jqXHR.abort() not cancelling the request but causing the browser to be unresponsive


I have a jQuery dialog which I use when making ajax calls. I want to be able to abort the current request when the dialog is closed. For this purpose I have defined a global variable called currentRequest and each time I setup an ajax request I assign it to this variable. In the close event of the dialog I check if currentRequst does not equal to undefined, if so I call currentRequst.abort(). But this does not seem to work as I am not able to reload the page. I have to wait until the time that would be needed to receive the response has elapsed. Here's the piece of the dialog:

...
 close:function(event,ui){dialogClosehandler();}
...

function dialogClosehandler(){
  alert('Dialog is closed');
 if(currentRequest!=undefined)
    currentRequest.abort();
}

As I said, this does not work. But if I abort it right when setting up the ajax call then it works.

currentRequest=$.ajax({
    url: "/GetData",
    type: 'POST',
    data: {} ,
    contentType: 'application/json',
    dataType: 'json',
}).abort();

Note the .abort().

Is there something I am missing?

EDIT: I think I need to expand the problem a bit more. I don't have any problem with for instance a button that just alerts hello or a link that takes user to google.com. But let's say I click on a button that makes another ajax request, or try to submit the form, so anything that would send a request to the server, in this case it won't have any effect unless some time has elapsed.

EDIT 2 For testing purposes I created 2 functions:

currentXHR=null;

function startAjax(){
  var url="/StartAjax";
  currenXHR=$.get(url,{},function(){alert('Ajax launched');});
}

function cancelAjax(){
  currentXHR.abort();
}

And this is the server side method (it's C#, ASP.NET MVC):

    public void StartAjax()
    {
        System.Threading.Thread.Sleep(10000);
    }

I have two buttons named start and cancel. When I click start and wait for the response I get "Ajax launched" alert after 10 seconds. But if I click cancel right after starting the request I don't receive any alert in the end, but still I can't refresh the page unless 10 seconds has elapsed. As you can see, the ajax request is asynchronous(otherwise I wouldn't be able to click teh cancel button), so this problem is related to something else.


Solution

  • After lots of digging and searching I came to this conclusion that this is the expected behavior because although the AJAX Request itself is async, this doesn't mean that the server will also handle this request on a separate thread. So as long as the main thread is busy with processing the previous request it won't proceed to another one. So, when reload button is pressed, a new request is indeed sent to the server, but the response for the new request is returned only after it's done with the previous one. So to me, the best option would be to process ajax request on a separate thread. This has 2 advantages:

    1. As the main thread is not blocked, response for a new request doesn't have to wait.
    2. By using CancellationToken we can also notify the server to cancel processing the response for a certain request, which prevents waste of resources.

    I think this article by Rick Anderson is a brilliant guide to do just that.