踩了setTimeout的坑
今天测试说,蒹葭同学,uat环境有个bug,秒杀产品还没结束,但是前端显示的是已经结束了,你看一下。
我内心OS:妈蛋,又出bug了。
不过还是乖乖的去debug了一下代码,最后排查出来是设置的定时器没有生效,直接执行了。
var timer = new Date('xxxx-xx-xx') - new Date('xxxx-xx-xx');
setTimeout(function(){
//TODO some code
},timer)
但是TODO里的代码是直接运行了。
what fuck!!怎么会这样,定时器竟然没有起作用。
于是查了一下mdn文档。
mdn文档这样写道:
Maximum delay value链接地址:https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout
Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed integer internally. This causes an integer overflow when using delays larger than 2147483647, resulting in the timeout being executed immediately.
大致翻译过来意思就是:
IE Chrome Safari Firefox 等32位的浏览器用延迟的时候,如果延迟的时间大于2147483647 毫秒的话,会导致超时,而立刻执行。顺便说一句,2147483647 这个毫秒数正好是
2的31次方-1
这样的话,就不难理解了,如果你设置的timer超过2的31次方,那么setTimeout就无效了,而立刻执行,这个也就解释了为什么设置的函数会立刻执行的原因了。
找到这个问题之后,也思考了下,为什么会出现这种炒鸡大的timer呢?原来是这个时间点都是接口restful下发的,没法控制,所以前端在兼容这个的时候,就采取了一个比较猥琐的办法,如果这个timer大于2147483647这个值,就赋值这个值,否则就是timer。
timer = timer > 2147483647 ? 2147483647 : timer;
【踩了setTimeout的坑】最终“完美解决”bug了。
推荐阅读
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- Tomcat8带来的坑
- 关于iOS录屏功能躺过的坑,给有需要的人
- 使用NSAttributedString富文本踩到的坑
- 浅析栈溢出遇到的坑及绕过技巧
- springmvc|springmvc 集成 Spring Data Elasticsearch 遇到的坑
- Android|Android Room 的坑
- 成为新媒体写作变现与自由撰稿人后(这些我走过的坑希望你别再走)
- 「每日一锤」友邦全佑至享荣耀全能保,业务员不愿告诉你的坑()
- 2018-03-28|2018-03-28 搭建RocketMQ踩的坑。。。