踩了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
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.

链接地址:https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout

大致翻译过来意思就是:

IE Chrome Safari Firefox 等32位的浏览器用延迟的时候,如果延迟的时间大于2147483647 毫秒的话,会导致超时,而立刻执行。

顺便说一句,2147483647 这个毫秒数正好是2的31次方-1
这样的话,就不难理解了,如果你设置的timer超过2的31次方,那么setTimeout就无效了,而立刻执行,这个也就解释了为什么设置的函数会立刻执行的原因了。
找到这个问题之后,也思考了下,为什么会出现这种炒鸡大的timer呢?原来是这个时间点都是接口restful下发的,没法控制,所以前端在兼容这个的时候,就采取了一个比较猥琐的办法,如果这个timer大于2147483647这个值,就赋值这个值,否则就是timer。

timer = timer > 2147483647 ? 2147483647 : timer;

😄😄最终“完美解决”bug了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInt...
    晚晴幽草阅读 1,686评论 1 18
  • 回想起第一次使用 setTimeout 函数的时候,设置的回调函数并不是立即执行,而是过了一段定义好的时间之后才执...
    YHuang阅读 1,785评论 0 1
  • 对集合的操作 关于d3.attr 一个可以处理很多情况的函数,当只传入一个参数时,如果是string,则返回该属性...
    陈坚生阅读 2,635评论 0 2
  • 黑黑的长长的走廊,走到灯下,灯亮,遇见零星的面熟的人,我想,我应该去阳台抽一支烟,每日临睡前,按照惯例我会在这里点...
    初之_阅读 290评论 0 2