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

| 我正在使用Direct Web Remoting(DWR)JavaScript库文件,并且仅在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)吞没了错误。 错误发生时,使用调试器检查调用堆栈。     
检测stackoverflows的问题是有时堆栈跟踪会消失,您将无法看到实际情况。 我发现一些Chrome \较新的调试工具对此有用。 点击
Performance tab
,确保已启用
Javascript samples
,您将得到类似的内容。 很明显这里是溢出的地方!如果单击
extendObject
,您将可以在代码中实际看到确切的行号。 您还可以看到可能会有所帮助的时机,也可能会看到红鲱鱼。 如果您实际上找不到问题,则另一个有用的技巧是在您认为问题出处的地方放置很多
console.log
语句。上面的上一步可以帮助您。 在Chrome浏览器中,如果您重复输出相同的数据,它将像这样显示,从而更清楚地指出问题所在。在这种情况下,堆栈在最终崩溃之前命中了7152帧:     
就我而言,我正在使用以下命令将大字节数组转换为字符串:
String.fromCharCode.apply(null, new Uint16Array(bytes))
bytes
包含数百万个条目,太大而无法容纳在堆栈中。     
就我而言,点击事件正在子元素上传播。因此,我不得不提出以下几点:   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开发者工具栏控制台中检查错误的详细信息,这将为您提供调用堆栈中的功能,并引导您进行导致错误的递归操作。     
如果出于某种原因需要无限的进程/递归运行,则可以在单独的线程中使用Webworker。 http://www.html5rocks.com/zh-CN/tutorials/workers/basics/ 如果要操纵dom元素并重绘,请使用动画 http://creativejs.com/resources/requestanimationframe/     
以我为例,两个jQuery模态相互重叠显示。防止这种情况解决了我的问题。     
几乎每个答案都指出,这只能由无限循环引起。事实并非如此,否则您可能会通过深度嵌套的调用来使堆栈超负荷运行(并不是说效率很高,但肯定在可能的范围内)。如果您可以控制JavaScript VM,则可以调整堆栈大小。例如:
node --stack-size=2000
另请参阅:如何增加Node.js中的最大调用堆栈大小     
检查您是否有一个调用自身的函数。例如
export default class DateUtils {
  static now = (): Date => {
    return DateUtils.now()
  }
}
    
我们最近在我们正在处理的管理站点中添加了一个字段-contact_type ...容易吗?好吧,如果您调用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-问题已解决。     
这也会导致
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,然后按Source选项卡,这将为您提供代码编译流程,并且您可以在代码中使用断点来查找。     
我也面临类似的问题,这里是细节  使用下拉徽标上传框上传徽标时
<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
    },
.....
    
我知道此线程很旧,但是我认为值得一提的是我发现了此问题的情况,因此它可以帮助其他人。 假设您有这样的嵌套元素:
<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地图,请检查纬度是否正以正确的格式传递到“ 31”中。就我而言,它们是作为未定义的传递的。     
在我的情况下的问题是因为我的子级路由与父级路径相同:
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获得了价值。     
遇到相同的问题,就没想到是什么原因开始怪Babel;) 使代码在浏览器中不返回任何异常:
if (typeof document.body.onpointerdown !== (\'undefined\' || null)) {
问题被严重创建|| (或)作为babel创建自己的类型检查的部分:
function _typeof(obj){if(typeof Symbol===\"function\"&&_typeof(Symbol.iterator)===\"symbol\")
所以删除
|| null
使通天塔翻译工作。     
有时由于转换数据类型而发生,例如,您有一个被视为字符串的对象。 例如,在js客户端中的nodejs中的nodejs中的socket.id不是字符串。要将其用作字符串,必须在前面添加单词String:
String(socket.id);
    
当未声明该变量时,我试图分配一个变量,即一个值。 声明变量修复了我的错误。     
那对我有用
$(\'form\')[0].submit()
    

要回复问题请先登录注册