使用MessageChannel实现标签页切换/浏览器置于后台,也不会停止的轻量定时器

50 阅读1分钟
function newTimer(callback, delay) {
  const startTime = performance.now();
  
  function check() {
    const elapsed = performance.now() - startTime;
    if (elapsed >= delay) {
      callback();
    } else {
      const channel = new MessageChannel();
      channel.port2.onmessage = check;
      channel.port1.postMessage(null);
    }
  }
  
  check();
}
​
newTimer(() => console.log('完成'), 500);
// 前台:500ms后执行 ✅  
// 后台:500ms后执行 ✅
  1. 检查很快:performance.now()和简单的数值比较很快

  2. MessageChannel很轻量:创建和销毁都很快

  3. 只在需要时运行:一旦时间到了就停止

  4. 比轮询好:不是无脑循环,而是事件驱动

兼容性也是极好的

image.png

image.png