0

I am trying to write a simple Jquery AJAX poll. I want to make sure that requests don't 'back up' in the browser if the web-server is being slow (which in my specific situation is very frequently...).

Here's my code:

(function poll() {
    $.ajax({
        url: CONFIG.apiBase,
        type: 'GET',
        data: { name: DESTINATIONS },
        traditional: true,
        success: updateDisplay,
        error: getError,
        complete: setTimeout(poll, 2000),
        timeout: 10000,
    });
})();

The way I think this should work is that if the request is successful, it will do updateDisplay and then wait 2 seconds before starting another poll request.

However, if my server is being super slow and can't respond within 10 seconds then getError will be called, the request will be cancelled and finally it will wait for 2 seconds before trying to poll again.

However, what actually happens is that the browser consistently polls the server every 2 seconds, causing the requests to back up if the server is being slow:

enter image description here

Am I fundamentally misunderstanding how timeout is supposed to work?

4
  • 2
    The problem is your setTimeout(poll, 2000) line - that's what's recursively calling your function every 2 seconds. Commented Nov 4, 2016 at 17:11
  • 1
    You are instantly calling setTimeout(poll, 2000),, try wrapping in a function closure.. function () { setTimeout(poll, 2000); } Commented Nov 4, 2016 at 17:11
  • You are setting the setTimeout id reference to the method... Commented Nov 4, 2016 at 17:12
  • @RoryMcCrossan He is wanting to retry after 2 seconds after the complete callback, but the setTimeout is been called, not when complete but when he's made the ajax call.. Commented Nov 4, 2016 at 17:14

1 Answer 1

3

The problem is your setTimeout(poll, 2000) line. At the moment it's calling your poll() function every 2 seconds as you don't wait for the previous request to finish. To fix this, wrap it in an anonymous function:

(function poll() {
    $.ajax({
        url: CONFIG.apiBase,
        type: 'GET',
        data: { name: DESTINATIONS },
        traditional: true,
        success: updateDisplay,
        error: getError,
        complete: function() {
            setTimeout(poll, 2000)
        },
        timeout: 10000,
    });
})();
Sign up to request clarification or add additional context in comments.

3 Comments

Perfect, that worked. So, perhaps I am misunderstanding something about Javascript. Does putting setTimeout()` directly after complete: cause setTimeout()to be called at the moment I call poll()?
Yes it does - but that's not exclusive to setTimeout(). Your code was executing the setTimeout() function immediately and setting its response value to the complete property. Returning a reference of a function (as in the above code) means that the logic within the function won't be executed until required. Similar to your success and error properties - you're providing references of updateDisplay() and getError() respectively. If you changed it to success: updateDisplay() then it would immediately execute the function and set it's response to the value of the property.
Thank you, that makes perfect sense and is obvious now that you've explained it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.