timeout

当前浏览器,除了IE9及以下版本、不确定的手机端之外,都支持给回调函数传参数:

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

回调函数中this指向的是global。

当第一个参数是一个字符串时,这个字符串会在全局上下文中用类似于eval的方式执行。

HTML5规范中,setTimeout最小触发时间是4ms,这个规范从2010开始被应用。在2010之前,这个时间是10ms。

有如下一段话不知怎么理解:

In addition to "clamping", the timeout can also fire later when the page (or the OS/browser itself) is busy with other tasks.

This API does not guarantee that timers will run exactly on schedule. Delays due to CPU load, other tasks, etc, are to be expected.

在当前浏览器中,为了尽快地执行回调函数,可以使用window.postMessage函数,参见如下代码(代码来源):

// Only add setZeroTimeout to the window object, and hide everything
// else in a closure.
(function() {
    var timeouts = [];
    var messageName = "zero-timeout-message";

    // Like setTimeout, but only takes a function argument.  There's
    // no time argument (always zero) and no arguments (you have to
    // use a closure).
    function setZeroTimeout(fn) {
        timeouts.push(fn);
        window.postMessage(messageName, "*");
    }

    function handleMessage(event) {
        if (event.source == window && event.data == messageName) {
            event.stopPropagation();
            if (timeouts.length > 0) {
                var fn = timeouts.shift();
                fn();
            }
        }
    }

    window.addEventListener("message", handleMessage, true);

    // Add the one thing we want added to the window object.
    window.setZeroTimeout = setZeroTimeout;
})();
setZeroTimeout(function() {
  console.log('setZeroTimeout', new Date().getTime());
});
setTimeout(function() {
  console.log('setTimeout', new Date().getTime());
}, 0);
console.log('other code', new Date().getTime());

在浏览器当中,setTimeout的delay参数在内部使用的是32位的有符号整型,因此如果这个参数大于2147483647,将会造成整型溢出,导致与delay=0没啥区别。

在浏览器(Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2 / Chrome 11)的非活动标签中,timeout触发不会超过每秒一次的频率。

比较详尽的描述请移步HTML5标准,其中包含很具体的timeout机制。

posted @ 2014-10-23 11:56  yibuyisheng  阅读(679)  评论(0编辑  收藏  举报