2016-04-25 7 views
0

Предположим, что у меня есть следующие функции опроса:функция опроса Аякса превышает стек вызовов

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); 
} 

Когда я вызываю его, обратный вызов никогда не вызывается, или это может быть, но мои console.logs никогда не появляются. Вместо этого через некоторое время я получаю

Uncaught RangeError: Maximum call stack size exceeded 

Таким образом, моя функция работает рекурсивно, но так, как хотелось бы. Я бы надеялся на аренду консольного журнала, прежде чем мои рекурсивные вызовы начнут печатать на консоли, но это не так. Я подтвердил, что моя базовая конечная точка работает правильно и возвращает json, поэтому я подозреваю, что в моем javascript-коде есть что-то, что мне не хватает. У кого-нибудь есть идея?

+0

Я бы добавил обработчик ошибок и 'console.log', что бы там ни появилось? Вы подтвердили на панели сети, что получаете ответ 200? – winhowes

+0

Не уверен, что это поможет, но вы можете столкнуться с проблемой с console.log, упомянутым здесь: http://stackoverflow.com/questions/8395718/javascript-funky-array-mishap. – Blue

+0

В вашем коде нет рекурсии в смысле вложенных вызовов функций. 'setTimeout' является асинхронным, и поэтому' $ .ajax'. Никакое выполнение 'pollingFunc' не имеет другого' pollingFunc' в стеке вызовов. Что-то еще происходит, что не показано в вашем вопросе. – Igor

ответ

1

Я плохо разбираюсь в js, но у меня были проблемы с setTimeout. Согласно w3school:

Показать окно предупреждения через 3 секунды (3000 миллисекунд):

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

Так что я думаю, что ваш код ждет 5 secondes перед вызовом сервера, а затем вы называете это каждый раз и сразу, когда вы получите ответ.

=> Чтобы устранить проблему, поставьте setTimeout внутри Функция успеха.

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); 
     } 
     }); 
    } 

Кстати, чтобы не воспроизвести такого рода проблемы, я хотел бы также объявить отдельно эту функцию, в соответствии с рекомендациями JQuery documentation.

+0

Да, я хотел иметь свой торт и есть тоже, имея функцию повторного использования, которая определяется за пределами обратного вызова успеха, поэтому я могу ее повторно использовать. Если не получится сделать это, я пойду дальше и приму этот ответ. – theamateurdataanalyst

+0

Я отредактировал свой ответ с адаптацией вашего кода, который все еще является многоразовой функцией, надеюсь, что это поможет! – vtellier

+1

«вы называете это каждый раз и сразу» - звоните, что сразу? Он называет 'pollingFunc', который только ставит в очередь другой' setTimeout' и выходит. – Igor