最大调用堆栈大小超过错误

我正在使用Direct Web Remoting(DWR)JavaScript库文件,并且仅在Safari(台式机和iPad)中出现错误,

它说

最大调用堆栈大小超出。

这个错误究竟意味着什么,它完全停止处理?

此外,任何修补程序的Safari浏览器(实际上在iPad Safari ,它说

JS:执行超时超时

我正在假设是相同的调用堆栈问题)

这意味着在你的代码中的某个地方,你正在调用一个函数,然后调用另一个函数等等,直到你达到了调用栈的限制。

这几乎总是因为一个没有被满足的基本情况的recursion函数。

查看堆栈

考虑这个代码…

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

这是几个电话后的堆栈

网络督察

正如你所看到的,调用堆栈会增长,直到遇到一个限制:浏览器硬编码堆栈大小或内存耗尽。

为了解决这个问题,确保你的recursion函数有一个基本的情况下,能够被满足…

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

你有时可以得到这个,如果你不小心导入/embedded相同的JS文件两次,值得检查在检查员的资源标签:)

你的代码中有一个recursion循环(即一个函数最终会自己调用,直到堆栈满了)。

其他浏览器要么有更大的堆栈(所以你得到一个超时而不是),或者由于某种原因吞下错误(也许是一个错误的尝试抓住)。

发生错误时使用debugging器检查调用堆栈。

在我的情况下,我发送input元素,而不是它们的值:

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

代替:

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

这使我的Chrome选项卡冻结了,甚至在页面无响应时显示“Wait / Kill”对话框。

在我的情况下,我使用以下方法将大字节数组转换为string:

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

bytes包含数百万个条目,这些条目太大而不适合堆叠。

检查Chrome开发工具栏控制台中的错误详细信息,这会给你调用堆栈中的函数,并指导你导致错误的recursion。

如果你需要一个无限的进程/recursion运行,你可以在一个单独的线程中使用webworker。 http://www.html5rocks.com/en/tutorials/workers/basics/

如果你想操纵DOM元素和重绘,使用animationhttp://creativejs.com/resources/requestanimationframe/

在我的情况下单击事件正在传播的子元素。 所以,我不得不放

e.stopProgration()

点击事件。

  $(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> 

检测stackoverflows的问题有时堆栈跟踪将放松,你将无法看到实际发生了什么。

我发现一些Chrome的新debugging工具对此很有用。

点击Performance tab ,确保Javascript samples已启用,您将得到类似这样的内容。

这里溢出的地方很明显! 如果你点击了extendObject你将能够在代码中看到确切的行号。

在这里输入图像描述

你也可以看到可能或不可能有用的时间或红鲱鱼。

在这里输入图像描述


另一个有用的技巧,如果你不能真正发现问题,就把大量的console.log语句放在你认为是问题的地方。 上面的上一步可以帮助你做到这一点。

在Chrome浏览器中,如果您重复输出相同的数据,则会显示如此,以显示问题更清楚的位置。 在这个例子中,堆栈在最终崩溃之前命中了7152帧:

在这里输入图像描述

这两个相同的代码调用,如果减less1,我的电脑上的Chrome 32工作,例如17905与17904.如果运行,他们将产生错误“RangeError:最大调用堆栈大小超过”。 看来这个限制不是硬编码的,而是取决于你机器的硬件。 看起来,如果作为一个函数被调用,这个自我强加的限制比作为一个方法被调用时要高,也就是说,当这个特定的代码作为一个函数被调用时,它使用较less的内存。

作为方法调用:

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

在我的情况下,两个jQuery模式显示堆叠在一起。 防止这个解决了我的问题。

你可以在crome浏览器中find你的recursion函数,按ctrl + shift + j,然后selectsource标签,这会给你代码编译stream程,你可以在代码中使用断点。

我也遇到类似的问题,这里是使用下拉式标志上传框上传标志的细节

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

控制台中的错误:

在这里输入图像描述

我通过从div标签中删除onclick="$('#filePhoto').click()"来解决这个问题。

我正面临同样的问题,我已经通过删除一个在AJAX上使用两次的字段名来解决它

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