0

Suppose I have the following polling function:

function pollingFunc(taskId){
 setTimeout(function() {
 $.ajax({
 url: '/endpoint',
 type: 'POST',
 data: { 'celery_task_id': taskId },
 success: function(response){
 if(response.celery_ready) {
 console.log('CELERY IS READY')
 } else {
 console.log('polling')
 pollingFunc(response.task_id)
 }
 }
 })
 }, 5000);
}

When I invoke it, the success callback is never invoked or it might be, but my console.logs never appear. Instead after a while I get

Uncaught RangeError: Maximum call stack size exceeded

So my function is running recursively, but in the way that I would want it to. I would hope at lease the console log before my recursive calls start would print in the console, but it doesn't. I have confirmed that my backend endpoint is operating correctly and is returning json, so I suspect there is something in my javascript code that I am missing. Anyone have any idea?

asked Apr 25, 2016 at 23:08
3
  • I would add an error handler as well and console.log whatever comes in there? Have you confirmed in the network panel that you're getting a 200 response? Commented Apr 25, 2016 at 23:14
  • Not sure if this helps but you may be running into the issue with console.log mentioned here: stackoverflow.com/questions/8395718/…. Commented Apr 25, 2016 at 23:25
  • There is no recursion in your code in the sense of nested function calls. setTimeout is asynchronous and so is $.ajax. No pollingFunc execution has another pollingFunc up the call stack. Something else is going on, that is not shown in your question. Commented Apr 26, 2016 at 1:35

1 Answer 1

1

I'm not good at js, but I had problems with setTimeout. According to w3school:

Display an alert box after 3 seconds (3000 milliseconds):

setTimeout(function(){ alert("Hello"); }, 3000);

So I think your code is waiting 5 secondes before calling your server, and then you call it each time and immediately when you get the answer.

=> To fix your problem, put the setTimeout inside the success function.

function pollingFunc(taskId){
 $.ajax({
 url: '/endpoint',
 type: 'POST',
 data: { 'celery_task_id': taskId },
 success: function(response){
 if(response.celery_ready) {
 console.log('CELERY IS READY')
 } else {
 console.log('polling')
 setTimeout(function() {
 pollingFunc(response.task_id);
 }, 5000);
 }
 });
 }

By the way, to not reproduce that kind of problem, I would also declare separately that function, as advised by JQuery documentation.

answered Apr 25, 2016 at 23:29
Sign up to request clarification or add additional context in comments.

4 Comments

Yeah I wanted to have my cake and eat too by having a reusable polling function that is defined outside of the success callback so I can reuse it. If there turns out to be no way to do this, I'll go ahead and accept this answer.
I edited my answer with an adaptation of your code which is still a reusable function, hope it will help!
"you call it each time and immediately" - call what immediately? He calls pollingFunc, which only queues another setTimeout and exits.
@Igor Yes, you're true.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.