Maximum call stack size exceeded как исправить google chrome

Это когда вызывается слишком много вложенных функций

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

  1. В первой функции находим на странице нужный элемент.
  2. Добавляем рамку с какой-то задержкой (чтобы она какое-то время была на экране).
  3. Вызываем функцию убирания рамки.
  4. Внутри второй функции находим тот же элемент на странице.
  5. Убираем рамку с задержкой.
  6. Вызываем первую функцию добавления рамки.

Код простой, поэтому делаем всё в одном файле:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Pulse</title>
	<style type="text/css">
	/*	рамка, которая будет моргать	*/
		.pulse { box-shadow: 0px 0px 4px 4px #AEA79F; }
	</style>
</head>
<body>
	<div id="pulseDiv"> 
    	<a href="#">
      		<div id="advisersDiv">
        		<img src="https://thecode.media/wp-content/uploads/2020/08/photo_2020-08-05-12.04.57.jpeg">
        	</div>
      	</a>
</div>
<!-- подключаем jQuery -->
<script src="https://yastatic.net/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
<!-- наш скрипт -->
<script type="text/javascript">
	// добавляем рамку
	function fadeIn() {
		// находим нужный элемент и добавляем рамку с задержкой
  	$('#pulseDiv').find('div#advisersDiv').delay(400).addClass("pulse");
  	// затем убираем рамку
  	fadeOut();
	};
	// убираем рамку
	function fadeOut() {
		// находим нужный элемент и убираем рамку с задержкой
   	$('#pulseDiv').find('div#advisersDiv').delay(400).removeClass("pulse");
   	// затем добавляем 
   	fadeIn();
	};
	// запускаем моргание рамки
	fadeIn();
</script>

</body>
</html>

Но при открытии страницы в браузере мы видим, что ничего не моргает, а в консоли появилась ошибка:

❌ Uncaught RangeError: Maximum call stack size exceeded

Что это значит: в браузере произошло переполнение стека вызовов и из-за этого он не может больше выполнять этот скрипт.

Переполнения стека простыми словами означает вот что:

  1. Когда компьютер что-то делает, он это делает последовательно — 1, 2, 3, 4.
  2. Иногда ему нужно отвлечься от одного и сходить сделать что-то другое — а, б, в, г, д. Получается что-то вроде 1, 2, 3 → а, б, в, г, д → 4.
  3. Вот эти переходы 3 → а и д → 4 — это компьютеру нужно запомнить, что он выполнял пункт 3, и потом к нему вернуться.
  4. Каждое запоминание, что компьютер бросил и куда ему нужно вернуться, — это называется «вызов».
  5. Вызовы хранятся в стеке вызовов. Это стопка таких ссылок типа «когда закончишь вот это, вернись туда».
  6. Стек не резиновый и может переполняться.

Что делать с ошибкой Uncaught RangeError: Maximum call stack size exceeded

Эта ошибка — классическая ошибка переполнения стека во время выполнения рекурсивных функций.

Рекурсия — это когда мы вызываем функцию внутри самой себя, но чуть с другими параметрами. Когда параметр дойдёт до конечного значения, цепочка разматывается обратно и функция собирает вместе все значения. Это удобно, когда у нас есть чёткий алгоритм подсчёта с понятными правилами вычислений.

В нашем случае рекурсия возникает, когда в конце обеих функций мы вызываем другую: 

  1. Функции начинают бесконтрольно вызывать себя бесконечное число раз.
  2. Стек вызовов начинает запоминать вызов каждой функции, чтобы, когда она закончится, вернуться к тому, что было раньше.
  3. Стек — это определённая область памяти, у которой есть свой объём.
  4. Вызовы не заканчиваются, и стек переполняется — в него больше нельзя записать вызов новой функции, чтобы потом вернуться обратно.
  5. Браузер видит всё это безобразие и останавливает скрипт.

То же самое будет, если мы попробуем запустить простую рекурсию слишком много раз:

Что означает ошибка Uncaught RangeError: Maximum call stack size exceeded

Как исправить ошибку Uncaught RangeError: Maximum call stack size exceeded

Самый простой способ исправить эту ошибку — контролировать количество рекурсивных вызовов, например проверять это значение на входе. Если это невозможно, то стоит подумать, как можно переделать алгоритм, чтобы обойтись без рекурсии.

В нашем случае проблема возникает из-за того, что мы вызывали вторые функции бесконтрольно, поэтому они множились без ограничений. Решение — ограничить вызов функции одной секундой — так они будут убираться из стека и переполнения не произойдёт:

<script type="text/javascript">
// добавляем рамку
function fadeIn() {
	// находим нужный элемент и добавляем рамку с задержкой
	$('#pulseDiv').find('div#advisersDiv').delay(400).addClass("pulse");
	// через секунду убираем рамку
	setTimeout(fadeOut,1000)
};
// убираем рамку
function fadeOut() {
	// находим нужный элемент и убираем рамку с задержкой
 	$('#pulseDiv').find('div#advisersDiv').delay(400).removeClass("pulse");
 	// через секунду добавляем рамку
	setTimeout(fadeIn,1000)
};
// запускаем моргание рамки
fadeIn();
</script>

Что означает ошибка Uncaught RangeError: Maximum call stack size exceeded

Вёрстка:

Кирилл Климентьев

Проблема

Некоторое время назад в работе над клиентской (javascript) частью движка josi возникла, кстати, достаточно часто встречающаяся проблема переполнения стека:
Uncaught RangeError: Maximum call stack size exceeded (google chrome)
В статье рассматривается решение без использования setTimout или setInterval.

Суть

Причина такого поведения известна и понятна, и в той или иной форме всегда вызвана следующим. Классическая(прямая) рекурсия порождает цепочку последовательных вызовов, что соответственно ведет к наполнению стека вызовов, однако, стек вызовов браузера достаточно мал, в chrome на момент тестирования это 500 вызовов, в safari, если не ошибаюсь, тоже. В любом случае- это предельное значение, а значит его можно превысить и получить exception. Естественно, столь долгое выполнение кода не желательно в принципе, и этого стоит избегать. И все же лично мне не хочеться полагаться на удачу, не смотря на то, что ситуация в которой пришлось столкнуться с проблемой на продакшен возникнуть не должна, я потратил время на изучение данного вопроса.

Решение

Классическим решением (имею ввиду подавляющее количество статей предлагающих его) является использование косвенной рекурсии посредством: setTimeout либо setInterval.

В качестве примера приведу простенькую рекурсивную функция, единственное назначение которой рано или поздно вернуть Вам предел размера стека вместе с exeption о превышении этого предела…

function f(args) 
{
     var self=this;
     var k=args.k;

     //вызываем себя же
     try
     {
         f({k:k+1});
     }
     catch(ex)
     {
          alert(k);
     }
}

та же бесполезная функция, но теперь теоретически бесконечная, разве что k переполнится

function f(args) 
{
     var self=this;
     var k=args.k;
     
     //косвенно вызываем себя же, через посредника setTimeout
     setTimeout(function(){ f({k:k+1}) }, 0);
}

Текущая функция сразу завершается за счет использования для рекурсии посредника setTimout, а следующий вызов выполняется по событию.
Отрицательной стороной такого подхода является его крайне низкая производительность, несмотря на то, что мы указываем нулевую задержку. Вызвана функция будет в зависимости от браузера в среднем не раньше чем через 10 мс. Но ведь мы боремся с превышением стека вызовов, а значит наша функция вызывается сотни раз, что означает потерю в производительности ~1 с на каждые 100 вызовов. Детальное тестирование нашел тут.
Самое простое, что пришло в голову — организовать симбиоз из попеременного использования прямого и косвенного вызовов, чтобы при достижении некоторого значения счетчика прерывать стек косвенным вызовом. Отчасти такое решение сейчас и используется. Но здесь тоже все не так просто, особенно если рекурсия представлена петлей из нескольких функций.
Вот простенький пример отражающий суть такого решения:

var max_call_i=300;
function f(args) 
{
     var self=this;
     var k=args.k;
     var call_i=args.call_i
     //alert(k);

     if (call_i>=max_call_i)
     {     
            //косвенно вызываем себя же, через посредника setTimeout
            setTimeout(function(){ f({k:k+1, call_i:call_i+1}) }, 0);
     }
     else
     {
           //напрямую вызываем себя же
           f({k:k+1, call_i:call_i+1});
     }
}

В моем коде проблема возникла в шаблонизаторе, который как раз незадолго до этого был переписан согласно новой парадигме. Не хотелось отказываться от принятой архитектуры. В тоже время реальное падение производительности составило 20-30% — что было просто чудовищно. Предложенное выше решение тоже не идеал: сохранялось падение производительности на 5-7%. Это меня не устроило: много гуглил, и напал на то, что нужно.
А это тест от туда же, из которого видно что, предложенный подход, в сравнении с setTimeout 0, гораздо более производительный, что на практике дало не более 3% падения производительности в моем случае…

Данное решение основано на связке window.postMessage и element.addEventListener, для меня достаточно кроссбраузерно (ie8+).

Я переработал функцию из приведенной выше статьи в AMD модуль. Возможно, кому-то это будет полезным…

define([], function () 
{
        
	return
       {
		
		args:							//аргументы
		{
			indirect_call:
			{
				f_arr:[],
				msg_name:"indirect_call-message",
				handler_f:null,
			}
		},
		
		/*** работа с событиями ***/

		f_indirect_call:function(f)
		{
			var self=this;
			
			//если это первый вызов то создаем обработчик события и привязываем к window
			if (t_uti.f_is_empty(self.args.indirect_call.handler_f))
			{
				//создаем обработчик события
				self.args.indirect_call.handler_f=function(event) 
				{
					if (event.source == window && event.data == self.args.indirect_call.msg_name) 
					{
						event.stopPropagation();
						if (self.args.indirect_call.f_arr.length> 0) 
						{
							var f = self.args.indirect_call.f_arr.shift();
							f();
						}
					}
				}
				
				window.addEventListener("message", self.args.indirect_call.handler_f, true);
			}
			
			self.args.indirect_call.f_arr.push(f);
			window.postMessage(self.args.indirect_call.msg_name, "*");
		},
      };
});

Hi everyone! I have a lot of info about this bug, and I think I found the cause:

  1. A bit more info about what how this bug shows itself. In development mode, everything is loaded with Javascript. Because the Javascript errors out, you only see a white page. In production, the page is pre-rendered, so you will see the initial page. However, the Javascript errors out, so you won’t be able to navigate.
  2. This is not a memory related issue. It think it’s very likely to be related to different maximum call stack sizes across platforms, but I haven’t been able to test this yet. Please ping me on Gitter if you’d like to help out with this.
  3. @Bouncey’s suggested solution did not work, but he’s on the right track.
  4. @Esslamb was instrumental in finding the source of this issue. He mentioned on Gitter that commenting out this line took away the error, but it still showed a white screen. I had previously done some profiling tests that showed a lot of React lifecycle methods, and @Esslamb’s findings made me realise what was going on.

First of all, here are my findings as to what the maximum call stack size is across browser (testing method from Axel Rauschmayer):

  • Windows/Firefox: 12383
  • Windows/Chrome: 8973
  • Windows/Edge: (can’t test in a blank tab, can’t get accurate result)

This seems to change with how much memory the tab is already consuming. As you can see, the limit in Chrome is quite a bit lower than in Firefox, which would explain why this ceiling is hit only in Chrome. I;d like to see what the results are on Mac/Chrome or Linux/Chrome.

It seems Gatsby mounts every single article as its own component on page load. My suspicions were confirmed by running a test with the exact same code, but only the Bootstrap articles, without any other articles, and using the original navdata.json, so the navigation was still the same. It ran fine.

Summary

Gatsby creates a component for every single article. Chrome on Windows can’t handle this many components being mounted.

Next steps

This error did not exist in older version of Gatsby. My next step is going through older versions that I can get to run and not have this issue. This would be a quick fix. Once that is working, I’ll go over to the Gatsby repo to see what can be done about this to fix the recent versions.


Sorry for the gigantic and messy post, I had a lot of information I wanted to get out as soon as I could.

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


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

Это говорит

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

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

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

JS: превышено время ожидания выполнения

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


Ответы:


Это означает, что где-то в вашем коде вы вызываете функцию, которая в свою очередь вызывает другую функцию и так далее, пока не достигнете предела стека вызовов.

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

Просмотр стека

Рассмотрим этот код …

(function a() {
    a();
})();

Вот стек после нескольких вызовов …

Веб-инспектор

Как видите, стек вызовов увеличивается до тех пор, пока не достигнет предела: размер стека в жестком коде браузера или исчерпание памяти.

Чтобы исправить это, убедитесь, что у вашей рекурсивной функции есть базовый случай, который можно встретить …

(function a(x) {
    // The following condition 
    // is the base case.
    if ( ! x) {
        return;
    }
    a(--x);
})(10);







Иногда вы можете получить это, если вы случайно импортируете / внедрите один и тот же файл JavaScript дважды, стоит проверить это на вкладке ресурсов инспектора.







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

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

Вместо:

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

Это заморозило мою вкладку Chrome до такой степени, что даже не отображало диалоговое окно «Ждать / убивать», когда страница перестала отвечать на запросы …





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

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

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





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

Я нашел некоторые из новых инструментов отладки Chrome полезными для этого.

Нажмите Performance tab, убедитесь, что Javascript samplesвключены, и вы получите что-то вроде этого.

Это довольно очевидно, где переполнение здесь! Если вы нажмете на кнопку, extendObjectвы сможете увидеть точный номер строки в коде.

введите описание изображения здесь

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

введите описание изображения здесь


Еще один полезный трюк, если вы не можете найти проблему, — это поместить множество console.logутверждений там, где вы думаете, что проблема. Предыдущий шаг выше может помочь вам в этом.

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

введите описание изображения здесь


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

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

bytes содержал несколько миллионов записей, что слишком велико для размещения в стеке.







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

e.stopPropagation ()

по событию клика:

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

Вот HTML-код:

 <div class="current-code">                                      
      <input type="submit" name="removediscountcouponcode" value="
title="Remove" class="remove-discount-button">
   </div>


Проверьте подробности ошибки в консоли панели инструментов Chrome dev, это даст вам функции в стеке вызовов и проведет вас к рекурсии, которая вызывает ошибку.



Почти каждый ответ здесь утверждает, что это может быть вызвано только бесконечным циклом. Это неправда, в противном случае вы могли бы перегрузить стек с помощью глубоко вложенных вызовов (не говоря уже о том, что это эффективно, но, безусловно, это возможно). Если у вас есть контроль над вашей виртуальной машиной JavaScript, вы можете настроить размер стека. Например:

node --stack-size=2000

Смотрите также: Как я могу увеличить максимальный размер стека вызовов в Node.js


В моем случае два мода jQuery показывали сложенными друг на друга. Предотвращение, которое решило мою проблему.


Недавно мы добавили поле на сайт администратора, над которым мы работаем — contact_type … easy right? Что ж, если вы вызываете select «type» и пытаетесь отправить его через вызов jquery ajax, это завершится неудачно с этой ошибкой, скрытой глубоко в jquery.js. Не делайте этого:

$.ajax({
    dataType: "json",
    type: "POST",
    url: "/some_function.php",
    data: { contact_uid:contact_uid, type:type }
});

Проблема в том, что type: type — я считаю, что мы называем аргумент «type» — наличие значения переменной с именем type не является проблемой. Мы изменили это на:

$.ajax({
    dataType: "json",
    type: "POST",
    url: "/some_function.php",
    data: { contact_uid:contact_uid, contact_type:type }
});

И переписал some_function.php соответственно — проблема решена.


Проверьте, есть ли у вас функция, которая вызывает сама себя. Например

export default class DateUtils {
  static now = (): Date => {
    return DateUtils.now()
  }
}


Это также может вызвать 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]);
}


Оба вызова идентичного кода ниже, если его уменьшить на 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);


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



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

<div>
      <div class="uploader greyLogoBox" id="uploader" flex="64" onclick="$('#filePhoto').click()">
        <img id="imageBox" src="{{ $ctrl.companyLogoUrl }}" alt=""/>
        <input type="file" name="userprofile_picture"  id="filePhoto" ngf-select="$ctrl.createUploadLogoRequest()"/>
        <md-icon ng-if="!$ctrl.isLogoPresent" class="upload-icon" md-font-set="material-icons">cloud_upload</md-icon>
        <div ng-if="!$ctrl.isLogoPresent" class="text">Drag and drop a file here, or click to upload</div>
      </div>
      <script type="text/javascript">
          var imageLoader = document.getElementById('filePhoto');
          imageLoader.addEventListener('change', handleImage, false);

          function handleImage(e) {
              var reader = new FileReader();
              reader.onload = function (event) {

                  $('.uploader img').attr('src',event.target.result);
              }
              reader.readAsDataURL(e.target.files[0]);
          }
      </script>
      </div>

CSS.css

.uploader {
  position:relative;
  overflow:hidden;
  height:100px;
  max-width: 75%;
  margin: auto;
  text-align: center;

  img{
    max-width: 464px;
    max-height: 100px;
    z-index:1;
    border:none;
  }

  .drag-drop-zone {
    background: rgba(0, 0, 0, 0.04);
    border: 1px solid rgba(0, 0, 0, 0.12);
    padding: 32px;
  }
}

.uploader img{
  max-width: 464px;
  max-height: 100px;
  z-index:1;
  border:none;
}



.greyLogoBox {
  width: 100%;
  background: #EBEBEB;
  border: 1px solid #D7D7D7;
  text-align: center;
  height: 100px;
  padding-top: 22px;
  box-sizing: border-box;
}


#filePhoto{
  position:absolute;
  width:464px;
  height:100px;
  left:0;
  top:0;
  z-index:2;
  opacity:0;
  cursor:pointer;
}

до исправления мой код был:

function handleImage(e) {
              var reader = new FileReader();
              reader.onload = function (event) {
                  onclick="$('#filePhoto').click()"
                  $('.uploader img').attr('src',event.target.result);
              }
              reader.readAsDataURL(e.target.files[0]);
          }

Ошибка в консоли:

введите описание изображения здесь

Я решил это, удалив onclick="$('#filePhoto').click()"из тега div.



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

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


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

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

<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 к дочернему элементу.

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


Если вы работаете с картами Google, то проверьте, правильно ли передаются new google.maps.LatLngданные о широте. В моем случае они передавались как неопределенные.


Проблема в моем случае заключается в том, что у меня есть дочерний маршрут с тем же путем, что и родительский:

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'prefix' },
      { path: 'home', loadChildren: './home.module#HomeModule' },
    ]
  }
];

Поэтому мне пришлось убрать линию детского маршрута

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
      { path: 'home', loadChildren: './home.module#HomeModule' },
    ]
  }
];


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



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

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

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

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

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

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

|| null

сделал вавилонскую транспиляцию.


В моем случае я по ошибке присвоил одно и то же имя переменной и функции val «class_routine_id»

var class_routine_id = $("#class_routine_id").val(class_routine_id);

должно быть вроде:

 var class_routine_id = $("#class_routine_id").val(); 



Я использую React-Native 0.61.5 вместе с ( npm 6.9.0 & node 10.16.1 )

Пока я устанавливаю любые новые библиотеки в Project, я получил

(например, npm install @ реагировать-навигация / родной —save)

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

для этого я стараюсь

sudo npm cache очистить —force

(Примечание: — Команда ниже, как правило, занимает от 1 до 2 минут в
зависимости от размера кэша npm )


Иногда это происходит из-за типа данных для преобразования, например, у вас есть объект, который вы рассматриваете как строку.

socket.id в nodejs либо в клиенте js, например, не является строкой. чтобы использовать его как строку, вы должны добавить слово String перед:

String(socket.id);


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

Объявление переменной исправило мою ошибку.

The error “Uncaught RangeError: Maximum call stack size exceeded” is common among programmers who work with JavaScript. It happens when the function call exceeds the call stack limit.

Let us look at the error in detail and the solution too.  

What do you Mean by Maximum Call Stack Error?

This error is caused mainly due to the following reasons –

Non-Terminating Recursive Functions

Your browser will allocate a certain amount of memory to all data types of the code you are running. But this memory allocation has a limit. When you call a recursive function, again and again, this limit is exceeded and the error is displayed.

So, call recursive functions carefully so that they terminate after a certain condition is met. This will prevent the maximum call stack to overflow and the error will not pop up.

Problematic Ranges

Some JS programs have ranges of inputs that the user can give. Other programs have functions that may go out of range. When this happens, browsers like Google Chrome will give you the Uncaught RangeError message. But Internet Explorer will crash.

To prevent this, always check the validity of input ranges and how the functions are working with the ranges.

Let us look at an example.

Example

<script>
fun_first();
function fun_first(){
console.log('Hi');
               fun_first();
}
</script>

Uncaught RangeError: Maximum call stack size exceeded

Explanation

In the above example, we are recursively calling fun_first() due to which the error is Uncaught RangeError encountered. The recursive function is called, which then calls another function, and goes on until it exceeds the call stack limit.   

Solution

We should call a recursive function with an If condition. When the code satisfies the condition, the function execution is stopped.

Code Example

<script>
var i=1;
fun_first(i);
function fun_first(i){
               if (i <= 10){
                              console.log('Hi');
                              i=i+1;
                              fun_first(i);
               }
}
</script>

In the above example, we have created an if condition to check the value of i. If the value of i reaches 10, the same function will not be called again.

Conclusion

The Uncaught RangeError is caused when the browser’s hardcoded stack size is exceeded and the memory is exhausted. So, always ensure that the recursive function has a base condition that can stop its execution.   

Понравилась статья? Поделить с друзьями:
  • Max payne an error has occurred in the graphics engine
  • Max payne 3 ошибка при запуске приложения 0xc0000906
  • Max payne 3 ошибка недостаточно памяти
  • Max payne 3 ошибка недостаточно места на жестком диске
  • Math domain error python asin