7

Ошибка: превышен максимальный размер стека вызовов

28

Я использую библиотеку JavaScript Direct Web Remoting (DWR) и получаю ошибку только в Safari (на настольном компьютере и iPad).

Ошибка выглядит следующим образом:

Maximum call stack size exceeded.

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

Кроме того, есть ли какие-либо решения для браузера Safari? На самом деле, на iPad Safari я получаю сообщение:

JS: execution exceeded timeout

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

5 ответ(ов)

1

В вашем случае вы отправляли элементы ввода вместо их значений:

$.post('', { registerName: $('#registerName') })

Вместо:

$.post('', { registerName: $('#registerName').val() })

Это привело к зависанию вкладки Chrome, до такой степени, что она даже не показывала диалог 'Ждать/Убить', когда страница стала неотзывчивой...

1

Вы можете иногда столкнуться с этой проблемой, если случайно импортируете или встраиваете один и тот же JavaScript файл дважды. Рекомендуется проверить это в вкладке "Ресурсы" в инструментах разработчика.

0

У вас в коде где-то есть рекурсивный цикл (т.е. функция, которая в конечном итоге снова и снова вызывает саму себя, пока стек не заполнится).

Другие браузеры, возможно, имеют больший размер стека (поэтому вместо этого вы получите тайм-аут) или по какой-то причине игнорируют ошибку (возможно, из-за неправильно расположенного блока try-catch).

Используйте отладчик, чтобы проверить стек вызовов, когда возникает ошибка.

0

В вашем случае вы сталкиваетесь с проблемой переполнения стека при попытке конвертировать большой массив байтов в строку с использованием следующего кода:

String.fromCharCode.apply(null, new Uint16Array(bytes))

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

Для решения этой проблемы вы можете использовать метод String.fromCharCode в цикле, разбивая массив на более мелкие части. Например:

let result = '';
const chunkSize = 65536; // Максимальное количество элементов для одной итерации
for (let i = 0; i < bytes.length; i += chunkSize) {
    result += String.fromCharCode.apply(null, new Uint16Array(bytes.slice(i, i + chunkSize)));
}

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

0

В вашем случае событие клика распространялось на дочерний элемент. Поэтому мне пришлось добавить следующее:

e.stopPropagation();

в обработчик события клика:

$(document).on("click", ".remove-discount-button", function (e) {
    e.stopPropagation();
    // какой-то код
});

$(document).on("click", ".current-code", function () {
    $('.remove-discount-button').trigger("click");
});

Вот HTML-код:

<div class="current-code">                                      
    <input type="submit" name="removediscountcouponcode" value="Удалить" title="Удалить" class="remove-discount-button">
</div>

Таким образом, с помощью e.stopPropagation() вы предотвращаете дальнейшую обработку события клика, что может быть полезно, если у вас есть несколько вложенных элементов, реагирующих на один и тот же клик.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь