Ошибка превышения максимального размера стека вызовов - PullRequest
442 голосов
/ 23 мая 2011

Я использую файл библиотеки JavaScript Direct Web Remoting (DWR) и получаю сообщение об ошибке только в Safari (для ПК и iPad)

Там написано

Превышен максимальный размер стека вызовов.

Что именно означает эта ошибка и останавливает ли она обработку полностью?

Также любое исправление для браузера Safari (На самом деле на iPad Safari написано

JS: превышен тайм-аут выполнения

Я предполагаю, что это та же проблема стека вызовов)

Ответы [ 27 ]

0 голосов
/ 05 января 2018

У меня была эта ошибка, потому что у меня было две функции JS с одинаковым именем

0 голосов
/ 04 января 2018

Я знаю, что эта ветка старая, но я думаю, что стоит упомянуть сценарий, в котором я нашел эту проблему, чтобы она могла помочь другим.

Предположим, у вас есть такие вложенные элементы:

<a href="#" id="profile-avatar-picker">
    <span class="fa fa-camera fa-2x"></span>
    <input id="avatar-file" name="avatar-file" type="file" style="display: none;" />
</a>

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

Таким образом, этот код не будет работать:

$('#profile-avatar-picker').on('click', (e) => {
    e.preventDefault();

    $('#profilePictureFile').trigger("click");
});

У вас есть два варианта, чтобы избежать этого:

  • Переместите ребенка наружу от родителя.
  • Применение функции stopPropagation к дочернему элементу.
0 голосов
/ 20 февраля 2014

Оба вызова идентичного кода ниже, если его уменьшить на 1, работают на Chrome 32 на моем компьютере, например, 17905 против 17904. При запуске в том виде, в каком они есть, выдается ошибка «RangeError: Превышен максимальный размер стека вызовов».Похоже, что этот предел не является жестко заданным, но зависит от аппаратного обеспечения вашей машины.Похоже, что если он вызывается как функция, то этот установленный предел выше, чем если бы он вызывался как метод, т.е. этот конкретный код использует меньше памяти при вызове как функция.

Вызывается как метод:

var ninja = {
    chirp: function(n) {
        return n > 1 ? ninja.chirp(n-1) + "-chirp" : "chirp";
    }
};

ninja.chirp(17905);

Вызывается как функция:

function chirp(n) {
    return n > 1 ? chirp( n - 1 ) + "-chirp" : "chirp";
}

chirp(20889);
0 голосов
/ 28 июня 2019

Это также может вызвать ошибку Maximum call stack size exceeded:

var items = [];
[].push.apply(items, new Array(1000000)); //Bad

То же самое здесь:

items.push(...new Array(1000000)); //Bad

Из Документов Mozilla :

Но будьте осторожны: при использовании этого способа вы рискуете превысить ограничение длины аргумента движка JavaScript.Последствия применения функции со слишком большим количеством аргументов (например, более десятков тысяч аргументов) варьируются в зависимости от движков (JavaScriptCore имеет жестко запрограммированный предел аргументов 65536), потому что это предел (в действительности, даже характер любого чрезмерно большого стека)поведение) не уточняется.Некоторые двигатели будут выбрасывать исключения.Более пагубно, другие будут произвольно ограничивать количество аргументов, фактически передаваемых прикладной функции.Чтобы проиллюстрировать этот последний случай: если бы такой механизм имел ограничение в четыре аргумента (фактические пределы, конечно, значительно выше), это было бы так, как если бы аргументы 5, 6, 2, 3 были переданы для применения в приведенных выше примерах,а не полный массив.

Так что попробуйте:

var items = [];
var newItems = new Array(1000000);
for(var i = 0; i < newItems.length; i++){
  items.push(newItems[i]);
}
0 голосов
/ 12 марта 2014

вы можете найти свою рекурсивную функцию в браузере crome, нажмите Ctrl + Shift + J, а затем вкладку исходного кода, которая дает вам процесс компиляции кода, и вы можете найти, используя точку останова в коде.

0 голосов
/ 05 июля 2019

натолкнулись на ту же проблему, не поняв, в чем дело, начали обвинять Бабеля;)

Наличие кода, не возвращающего никаких исключений в браузерах:

if (typeof document.body.onpointerdown !== ('undefined' || null)) {

проблема была плохо создана || (или) part, поскольку babel создает собственную проверку типа:

function _typeof(obj){if(typeof Symbol==="function"&&_typeof(Symbol.iterator)==="symbol")

так что удаление

|| null

сделанная трансплантация бабла сработала.

0 голосов
/ 08 ноября 2017

Я столкнулся с той же проблемой, я решил ее, удалив имя поля, которое дважды использовалось в ajax, например

    jQuery.ajax({
    url : '/search-result',
    data : {
      searchField : searchField,
      searchFieldValue : searchField,
      nid    :  nid,
      indexName : indexName,
      indexType : indexType
    },
.....
...