Я реализовал функцию, которая рекурсивно решает. Потому что иногда нужно делать асинхронно, я не могу использовать простой цикл /while
и должен использовать рекурсивные вызовы функций.Предотвращение InternalError: слишком много рекурсии
В очень абстрактном фрагменте это будет означать следующее:
function doStuff(){
// async or sync things -> depends on several circumstances
doStuff();
}
doStuff();
Это прекрасно работает. Но, как и следовало ожидать, это вызывает проблемы, когда предел максимального рекурсивного вызова превышен. Иногда мне нужно обрабатывать более 25 000 вызовов, что вызывает InternalError: too much recursion
в последнем Firefox (50.0a2).
Я обнаружил, что ловить InternalError и повторно вызвав функцию обратного вызова с тайм-аут работы:
function doStuff(){
// async or sync things -> depends on several circumstances
try{
doStuff();
} catch(e if e instanceof InternalError){
setTimeout(function(){
doStuff();
}.bind(this), 25);
}
}
doStuff();
Но это выглядит Hacky и некрасиво. Поэтому я спрашиваю себя, каким будет предпочтительный способ обхода этой ситуации - когда вы не можете обрабатывать вещи в цикле и использовать рекурсивные вызовы функций?
Использовать цикл, поскольку устранение длинных хвостовых вызовов не реализовано в текущих браузерах. Обратите внимание, что циклы столь же выразительны, как и рекурсия хвоста, и петли со своей собственной структурой данных стека столь же выразительны, как и не хвостовая рекурсия. Не используйте 'setTimeout'. – ftor
1. Почему бы не использовать 'setTimeout'? Я знаю, что это уродливо, но что это за недостатки? 2. Я не могу использовать обычный цикл, поскольку мне нужно запустить асинхронный код через некоторое время. Цикл будет продолжать работать ... – dude
'setTimeout' невероятно медленный. Однако я не понимаю ваш псевдокод. 'doStuff' не принимает никаких аргументов и ничего не возвращает. Рекурсивный случай блокируется. Он ведет себя точно как обычный цикл. А как насчет базового случая? – ftor