Skip to content
本页目录

setTimeout

HTML 标准 规定, 当setTimeout嵌套层级为 5 次, 浏览器强制执行 4 毫秒的最小超时

其中, Chrome 浏览器在不满足嵌套层级的情况下,最小延迟时间设置为 1ms。

js
setTimeout(() => console.log(5), 5);
setTimeout(() => console.log(4), 4);
setTimeout(() => console.log(3), 3);
setTimeout(() => console.log(2), 2);
setTimeout(() => console.log(1), 1);
setTimeout(() => console.log(0), 0);
// 1 0 2 3 4 5
  • 零延时定时器

利用 postMessage 模拟定时器

js
(function () {
  var timeouts = [];
  var messageName = 'zero-timeout-message';

  // 保持 setTimeout 的形态,只接受单个函数的参数,延迟始终为 0。
  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);

  // 把 API 添加到 window 对象上
  window.setZeroTimeout = setZeroTimeout;
})();

应用场景(TODO):

React 时间切片 - React Scheduler 为什么使用 MessageChannel 实现

  • 毫秒级别定时器

利用 window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。(该回调函数会传入 DOMHighResTimeStamp 参数,该参数与 performance.now() 的返回值相同,它表示 requestAnimationFrame() 开始执行回调函数的时刻, 该时间戳是一个十进制数,单位为毫秒,最小精度为 1ms)