最大调用堆栈大小超过错误
我正在使用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 }, .....