错误 RangeError:使用 setTimeout 时超出了最大调用堆栈大小

Posted

技术标签:

【中文标题】错误 RangeError:使用 setTimeout 时超出了最大调用堆栈大小【英文标题】:ERROR RangeError: Maximum call stack size exceeded when using setTimeout 【发布时间】:2019-11-25 14:40:07 【问题描述】:

我正在尝试实现一种方法,其中在固定时间间隔后发生角度材料选项卡更改。我尝试在 javascript 中使用 setInterval,但它的工作并不可靠(选项卡更改是随机发生的)。 下面发布的代码有效,但几个小时后浏览器冻结并且控制台显示此错误:

ERROR RangeError: 超出最大调用堆栈大小

togglePlay(): void 
    this.isAnimationPlaying = !this.isAnimationPlaying;
    if (this.isAnimationPlaying) 
        this.setIndex();
     else 
        clearTimeout();
    


setIndex() 
    this.selectedIndex = (this.selectedIndex + 1) % this.matTabLength;
    this.changeDetectorRef.detectChanges();
    if (this.isAnimationPlaying) 
        setTimeout(this.setIndex.bind(this), this.transitionSpeed);
     else 
        clearTimeout();
    

我尝试像这样在 setTimeout 方法中传递 transitionSpeed:

setTimeout(this.setIndex, this.transitionSpeed, this.transitionSpeed);

setIndex(transitionSpeed: number, selectedIndex: number, matTabLength: number) 
    this.selectedIndex = (selectedIndex + 1) %.matTabLength;
    if (this.isAnimationPlaying) 
        setTimeout(this.setIndex, transitionSpeed, selectedIndex, matTabLength);
     else 
        clearTimeout();
    

但如果该方法被第二次调用,this.transitionSpeed 为空。

非常感谢任何帮助

编辑:

将代码更改为此,但几个小时后仍然出现相同的错误:

togglePlay(): void 
    this.isAnimationPlaying = !this.isAnimationPlaying;
    if (this.isAnimationPlaying) 
        this.setIndex();
     else 
        clearTimeout(this.timerId);
    


setIndex() 
    this.selectedIndex = (this.selectedIndex + 1) % this.matTabLength;
    this.changeDetectorRef.detectChanges();
    if (this.isAnimationPlaying) 
        clearTimeout(this.timerId);
        this.timerId = setTimeout(this.setIndex.bind(this), this.transitionSpeed);
     else 
        clearTimeout(this.timerId);
    

EDIT2: 在更改选项卡时,会调用 TabChange 事件。 代码:

    tabChanged(event) 
        this.themeClassesToRemove = Array.from(this.overlayContainer.getContainerElement().classList).filter((item: string) => item.includes('-template'));
        if (Array.from(this.overlayContainer.getContainerElement().classList).filter((item: string) => item.includes('-template')).length) 
            this.overlayContainer.getContainerElement().classList.remove(...this.themeClassesToRemove);
        
        const label = event.tab.textLabel;
        if (label.toLocaleLowerCase() === '1') 
            this.templateService.default_template = this.templateService.grey_template;
         else if (label.toLocaleLowerCase() === '2') 
            this.templateService.default_template = this.templateService.green_template;
         else if (label.toLocaleLowerCase() === '3') 
            this.templateService.default_template = this.templateService.red_template;
         else 
            this.templateService.default_template = this.templateService.blue_template;
        
        this.overlayContainer.getContainerElement().classList.add(this.templateService.default_template);
        window.dispatchEvent(new Event('resize'));
    

这是唯一的方法,在超时之外调用。根据这个post,必须有一直调用的递归方法。

【问题讨论】:

Maximum call stack size exceeded error的可能重复 【参考方案1】:

setTimeout。返回一个计时器 ID,然后您可以在 clearTimeout 中使用它来清除它:

timerId = setTimeout(this.setIndex.bind(this), this.transitionSpeed);      

clearTimeout(timerId);

【讨论】:

我试过这个,几个小时后我仍然得到同样的错误。更改的代码在我的编辑中

以上是关于错误 RangeError:使用 setTimeout 时超出了最大调用堆栈大小的主要内容,如果未能解决你的问题,请参考以下文章

渲染中的 Vue 错误:“RangeError:无效的数组长度”

RangeError,语法错误:无效的正则表达式

RangeError ReferenceError SyntaxError TypeError URIError

Angular 5 表单组件导致错误:“RangeError:超出最大调用堆栈大小”

Nowjs:[RangeError:超出最大调用堆栈大小]

RangeError:WebAssembly.Instance():内存不足:wasm 内存