【问题标题】:Setting and using a single Global setTimeout?设置和使用单个全局 setTimeout?
【发布时间】:2019-03-06 03:00:52
【问题描述】:

刚刚偶然发现this very old question 中关于清除所有 setTimeouts 的评论。

该评论引起了我的兴趣,因为它实际上并没有直接解决问题,而是为跟踪多个计时器的问题提供了一个非常有趣的替代解决方案,但遗憾的是,他没有提供如何实施的示例:

使用全局超时,您的所有其他函数都会派生计时 从。这将使一切运行得更快,更容易管理, 虽然它会为您的代码添加一些抽象...

...我的意思是你有一个全局超时运行一次 50 毫秒。需要计时元素的所有其他功能将 然后从全局超时中获取它。谷歌切换到这个 效率,虽然我再也找不到引用它的文章了。

如何在全局空间中设置我假设的命名计时器,然后在多种情况下在其他地方引用它?

例如,如果我们在全局空间中有这样的东西:

let myGlobalTimer = setTimeout(function(){ myFunc(); }, 50);

这只会每 50 毫秒运行一次 myFunc

我很确定您不能将动态函数名称传递给setTimeout,那么如何实现呢?

【问题讨论】:

标签: javascript settimeout


【解决方案1】:

每次触发超时时,您都可以通过数组或Set 函数运行超时。要添加每次迭代都运行的函数,请将其添加到 Set;要阻止它运行,请将其从Set 中删除。例如:

const fns = new Set();
function runAllTasks() {
  for (const fn of fns) {
    fn();
  }
  // Run every 500 ms:
  setTimeout(runAllTasks, 500);
}

fns.add(() => console.log('fn one running'));
const fn2 = () => console.log('fn two running');
fns.add(fn2);
runAllTasks();

// example, remove fn2 from the Set after 1300ms:
setTimeout(() => {
  fns.delete(fn2);
}, 1300);

当然,您也可以使用数组,但是当集合中项目的顺序无关紧要时,Set 更合适。

【讨论】:

  • 哇,这真是令人印象深刻!所以这样做,无论您向 Set 添加多少功能,都只会运行 1 个 setTimeout?
  • 你有没有机会在 vanilla JS 而不是 ES2015 中推出这个版本?我只是通过 babel 反编译器运行它,它看起来很疯狂,哈哈。 pastebin.com/5CZ5tUjN
  • @spice 如果不想使用for..of,可以改用forEachfns.forEach(fn => fn())
  • @spice 这个 ES2015 是 Vanilla JS
  • @spice - 仅当您根据所有函数完成后下一个 500 毫秒滴答的剩余时间为每个 setTimeout 调用设置延迟时。这个答案将在最后一个函数完成后将延迟设置为 500 毫秒,这甚至不会给出 500 毫秒的延迟。
猜你喜欢
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 2014-11-27
  • 2018-12-21
  • 1970-01-01
相关资源
最近更新 更多