tags:

views:

44

answers:

4

I read a lot of questions, but they doesn't working in my case. My situation is: my ajax query to database to insert infromation. But in my web-application user can click on buttons very quick so previous ajax query is not finished, and there is where bugs are appear. All i need to do is a delay between queries, so future queries will do only after previous is done. Here is a code:

$('#save').click(function(){

    var user_input=$('#user').val();
    var section=$('#section').val();

    $('#loading_info').append('<p><img src="Images/loading.gif" alt="loading" id="loading"/></p>');
    $.ajax({
        url: 'submit_db.php',
        type: 'POST',
        data: 'section='+section+'&user_input='+user_input,
        success: function(result){
            $('#response').remove();
            $('#loading_info').append('<p id="response">' + result + '</p>');
            $('#loading').fadeOut(500, function(){
                $(this).remove();
            });
        }
    });
    return false;
});

What i tested and not working: insert timeout:3000 into ajax - 1 query is ok, but after this, the whole application freezes; set timeout using ajaxSetup() - the same situation. Tested setInterval function and put ajax query to it - but after it there were no ajax, application opened an implementing php file and freezes.

This not working:

$('#save').click(function(){
    var t=setTimeout(function(){
    var user_input=$('#user').val();
    var section=$('#section').val();

    $('#loading_info').append('<p><img src="Images/loading.gif" alt="loading" id="loading"/></p>');
    $.ajax({
        url: 'submit_db.php',
        type: 'POST',
        data: 'section='+section+'&user_input='+user_input,
        success: function(result){
            $('#response').remove();
            $('#loading_info').append('<p id="response">' + result + '</p>');
            $('#loading').fadeOut(500, function(){
                $(this).remove();
            });
        }
    });
    return false;            
    },3000);

});

And this is not working too:

$('#save').click(function(){

    var user_input=$('#user').val();
    var section=$('#section').val();

    $('#loading_info').append('<p><img src="Images/loading.gif" alt="loading" id="loading"/></p>');
    $.ajax({
        url: 'submit_db.php',
        type: 'POST',
        timeout: 3000,
        data: 'section='+section+'&user_input='+user_input,
        success: function(result){
            $('#response').remove();
            $('#loading_info').append('<p id="response">' + result + '</p>');
            $('#loading').fadeOut(500, function(){
                $(this).remove();
            });
        }
    });
    return false;
});

And finally this is not work too:

$.ajaxSetup({
  timeout:3000,
});

Thanks in advance

A: 

Use a sentinel variable so that only one request can happen at a time. If it makes sense for the user to be able to have more than one request going then implement a queue for the requests, where the call to process the next element in the queue happens after the previous request has been handled.

Ignacio Vazquez-Abrams
+1  A: 

What I suggest is to create a boolean and dissable any button.

Create a boolean called "buttonPressed", this is set to false. When a submit is made, you check in your code if "buttonPressed" is set to false. If this isn't set to false, skit the AJAX request, otherwise set the buttonPressed to true and do the AJAX request. When the request is done, set the buttonPressed back to false and a new buttonpress will be allowed.

Regards, Paul Peelen

Paul Peelen
Wow - thanks man
dsplatonov
np. Glad I could help :)
Paul Peelen
+1  A: 

The problem is propably in that: user clicks 3 times in second, and afeter 3 seconds of timeouts, three quersies and sended in one second.

Use setTimeout, but clear this timeout everytime user clicks, so every time user clicks, timer is reseted, and you don't have to worry about query "queue".

Other solution is to detect does timer working, and ignore or queue user click (queue by creating new timet with value of 3000 + rest time of the actual timer

killer_PL
+1  A: 

Paul Peelen's answer is probably the best one for you, but another safe solution would be to queue your requests. It will allow your code to execute asynchronously but still sequentially and even (potentially) allows you to kill duplicate requests before they even leave the machine. The way I've done this is something like this:

  1. Create an array to hold your requests.
  2. When the user's action causes a request, throw it into the end of the queue.
  3. Immediately call a queue processor. If a previous requests hasn't resulted in a response yet, do nothing -- just leave it in the queue. Otherwise, remove the first item from the queue and process it. At this point, you could also look through the other queued requests and remove duplicates, or push high-priority requests to the top of the queue.
  4. When the response is received, send it to wherever it needs to go and tell the queue processor to process the next request.

It's actually pretty simple to build, and I'm sure there are better variations out there. If server stability is a possible issue, you should build in some sort of process to kill dead requests (zombies).

Andrew