V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
good
V2EX  ›  JavaScript

遇到一个 Js 定时器的坑,哪位大神知道是什么原因?

  •  
  •   good · 2017-03-31 19:55:57 +08:00 · 3604 次点击
    这是一个创建于 2829 天前的主题,其中的信息可能已经有所发展或是发生改变。
    setTimeout("alert('ok');",1580870100); 
    setTimeout("alert('ok1');",15808701000);//这条会立即执行
    setTimeout("alert('ok');",1580870100000);
    
    12 条回复    2017-04-03 13:27:23 +08:00
    lovedebug
        2
    lovedebug  
       2017-03-31 20:05:29 +08:00
    定时器本来就不会按顺序执行的。
    定时器只是将任务派发给异步事件管理器,什么时候执行按什么顺序执行是不确定的
    HerrDu
        3
    HerrDu  
       2017-03-31 20:12:09 +08:00
    第二个时间太大崩了? 崩溃了之后直接执行?
    acthtml
        4
    acthtml  
       2017-03-31 20:14:55 +08:00   ❤️ 1
    超过 32bit 的最大数字了,会归一,源码就是这么写的。

    // Timeout values > TIMEOUT_MAX are set to 1.
    var TIMEOUT_MAX = 2147483647; // 2^31-1
    myusakura
        5
    myusakura  
       2017-03-31 20:28:54 +08:00
    @acthtml 那第三条也会归一吗,为什么第三条不显示?
    isayme
        6
    isayme  
       2017-03-31 21:31:01 +08:00
    xuzicn
        7
    xuzicn  
       2017-04-01 10:36:57 +08:00
    @isayme 然而 1580870100000 为啥没有立即执行,百思不得姐
    isayme
        8
    isayme  
       2017-04-01 14:32:00 +08:00
    @xuzicn @myusakura 原因应该是这样的:
    // 以前是这么处理 delay 时间的
    delay = delay & 2147483647

    // 现在是这么处理 delay 时间的
    if (delay > 2147483647) {
    delay = 1
    }
    isayme
        9
    isayme  
       2017-04-01 14:40:13 +08:00
    @xuzicn @myusakura 貌似说反了~~~
    xuzicn
        10
    xuzicn  
       2017-04-01 15:14:18 +08:00
    @isayme 这也说不通啊
    isayme
        11
    isayme  
       2017-04-02 10:16:34 +08:00
    @xuzicn Node.js 里是大于 2147483647 就强行改为 1. Chrome/Firefox 还没找到...

    见: https://github.com/nodejs/node/blob/master/lib/timers.js#L390
    isayme
        12
    isayme  
       2017-04-03 13:27:23 +08:00   ❤️ 1
    @xuzicn 测试下来, 浏览器是先 delay & 0x0ffffffff 处理 delay 时间.

    15808701000 处理后是一个负数(1371168184), 所以会被立即执行.
    1580870100000 处理后是正数 322135072, 本质上还会有延迟.

    所以: setTimeout(function () {console.log('expect 1')}, Math.pow(2, 32) + 5000) 还是延迟 5 秒执行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2685 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:15 · PVG 20:15 · LAX 04:15 · JFK 07:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.