php栈溢出,解决栈溢出的问题

前言

bVbOIuu

主要报错信息:ERROR RangeError: Maximum call stack size exceeded

这周主要研究了栈溢出问题的原因及如何解决。

探究原因

通过控制台的报错信息得知,由于是重复请求了一个后台地址导致。但是,这是如何引起的呢。

我们找到前台请求的相关代码。发现是一个拦截器。拦截器的主要作用是对请求的地址加入/api/前缀。然后在其构造函数下进行打印,发现重复进行了构造函数方法。

猜想可能是哪个部分进行了重复请求造成了重复调用拦截器。

我们再看看我们的初始化方法constructor(private router: Router,

private commonService: CommonService,

private settingService: SettingService) {

this.ngOnInit();

}

ngOnInit() {

this.settingService.findByKey(SettingConst.customerServicePhoneNumber)

.subscribe(setting => this.customerServicePhoneNumber = setting.value);

}

在构造函数里写ngOnInit方法是因为这和我们不同的组件c层不同,c层会初始化时主动调用ngOnInit方法。而这里并不会主动调用。

我们看到ngOnInit方法进行了url请求,而我们的拦截器就是在url请求的时候拦截器进行了构造函数。

这就在构造函数的url请求与请求时进行构造函数之间进行了死循环。当循环的次数越多,就造成了栈溢出。

但是却不是每次url请求都会进行构造函数。如果是这样,那就代表着拦截器会每触发一次进行一次死循环。也就是多例模式。

但是经过测试发现,在进入系统后进行删除老师或者增加老师的请求后台地址的操作时,并没有进行拦截器的构造函数。

这也就说明拦截器是单例模式。

理解单例模式与多例模式。

举个例子:我们在点外卖时会有外卖小哥给我们配送。单例模式就是我点十次外卖都是一个外卖小哥配送,其他人点外卖也会由他来送。而多例模式就是每点一次外卖就会有一个不同的人来配送,并且每次送外卖的人都不相同。

在之后的请求时,并没有执行初始化函数,也说明了没有实例化拦截器这个类,所以这是一个单例模式。但是为什么单例模式下在构造函数中请求时会再次执行构造函数。

解决

在老师的指导下,知道了其中的原因,在执行拦截器构造函数时,此时是没有拦截器的。系统在判定没有拦截器后继续进行一个新的实例化。继续进行构造函数,进而造成了死循环。

解决办法就是异步处理ngOnInit() {

setTimeout(() => {this.settingService.findByKey(SettingConst.customerServicePhoneNumber)

.subscribe(setting => this.customerServicePhoneNumber = setting.value);}, 0)

}

setTimeout方法就是对某段代码进行开启一个新的线程并执行。虽然是0秒后执行,但是是一个异步执行。

我们在进行setTimeout方法的同时。接着往下执行。执行完毕后,也就代表着构造器对象已经构造好了。以后再次进行请求时,就使用第一次构造好的拦截器。就不会发生死循环问题了。

当然,我们也可以根据实际情况取消在构造函数下进行url请求。

总结

在此感谢老师的指导,也感谢张文达同学在此过程中的帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值