有一种方法可以配置javascript的setInterval方法来立即执行该方法,然后与计时器一起执行
当前回答
在ES2017中,最好完全避免使用setInterval。
下面的解决方案具有更清晰的执行流程,可以防止函数需要比预期时间更长的时间才能完成的问题,并允许异步操作。
const timeout = (delayMs) => new Promise((res, _rej) => setTimeout(res, delayMs));
const DELAY = 1_000;
(async () => {
while (true) {
let start_time = Date.now();
// insert code here...
let end_time = Date.now();
await timeout(DELAY - (end_time - start_time));
}
})();
其他回答
/ / YCombinator 匿名函数(fnc) { 返回函数(){ fnc。应用(fnc参数); 返回fnc; } } //第一次调用: setInterval(匿名函数(){ console.log(“酒吧”); }) (), 4000); //不调用第一次: setInterval(匿名函数(){ console.log (" foo "); }), 4000); //或者简单: setInterval(函数(){ console.log(“巴兹”); }, 4000);
好吧,这太复杂了,让我说得简单点:
函数hello(status) { console.log(‘世界’,+ + status.count); 返回状态; } setInterval(hello, 5 * 1000, hello({count: 0}));
函数的即时异步调用存在一个问题,因为标准的setTimeout/setInterval即使直接将其设置为0,也具有大约几毫秒的最小超时。这是由浏览器特定的工作引起的。
一个具有REAL零延迟的代码示例,可在Chrome, Safari, Opera中工作
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
你可以在这里找到更多信息
在第一次手动调用之后,您可以用函数创建一个间隔。
有一个方便的npm包叫做firstInterval(完全披露,它是我的)。
这里的许多示例都不包括参数处理,在任何大型项目中更改setInterval的默认行为都是有害的。从文档中可以看出:
这种模式
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
等于
firstInterval(callback, 1000, p1, p2);
如果您使用的是老式浏览器,并且不想要依赖项,那么可以简单地从代码中剪切和粘贴。
最简单的方法是自己第一次直接调用函数:
foo();
setInterval(foo, delay);
然而,有很好的理由避免setInterval——特别是在某些情况下,整个setInterval事件负载可以在彼此之后立即到达,没有任何延迟。另一个原因是,如果你想停止循环,你必须显式调用clearInterval,这意味着你必须记住从最初的setInterval调用返回的句柄。
因此,另一种方法是让foo在后续调用中使用setTimeout来触发自身:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
这保证了调用之间至少有一个延迟间隔。如果需要的话,它还使取消循环变得更容易——当达到循环终止条件时,您不需要调用setTimeout。
更好的是,你可以把这一切都包装在一个立即调用的函数表达式中,它创建了函数,然后像上面一样再次调用自己,并自动启动循环:
(function foo() {
...
setTimeout(foo, delay);
})();
它定义了函数,并开始了整个循环。
由于同样的问题,我偶然发现了这个问题,但如果你需要完全像setInterval()那样运行,那么没有一个答案可以帮助你,唯一的区别是函数在开始时立即被调用。
以下是我对这个问题的解决方案:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
该解决方案的优点:
使用setInterval的现有代码可以很容易地通过替换进行调整 在严格模式下工作 它使用现有的命名函数和闭包 您仍然可以使用返回值并稍后将其传递给clearInterval()
例子:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
坦率地说,如果你真的需要使用setInterval,那么你也可以替换原来的setInterval。因此,在现有代码之前添加此代码时不需要更改代码:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
尽管如此,上面列出的所有优点都适用于这里,但没有必要进行替换。
推荐文章
- 什么时候JavaScript是同步的?
- 如何在Typescript中解析JSON字符串
- Javascript reduce()在对象
- 在angularJS中& vs @和=的区别是什么
- 错误"Uncaught SyntaxError:意外的标记与JSON.parse"
- JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?
- 在Javascript中~~(“双波浪号”)做什么?
- 谷歌chrome扩展::console.log()从后台页面?
- 未捕获的SyntaxError: