有一种方法可以配置javascript的setInterval方法来立即执行该方法,然后与计时器一起执行
当前回答
这个例子建立在@Alnitak的回答上,但是使用await Promise在循环循环中进行更细粒度的控制。
比较的例子:
let stillGoing = true;
(function foo() {
console.log('The quick brown fox did its thing');
if (stillGoing) setTimeout(foo, 5000);
})();
foo();
在上面的例子中,我们调用foo(),然后它每5秒调用一次自己。
但是如果,在未来的某个时候,我们为了停止循环而将stillGoing设为false,即使在发出停止命令之后,我们仍然会得到一个额外的log行。这是因为在任何给定的时间,在我们将stillGoing设置为false之前,当前迭代将已经创建了一个超时来调用下一次迭代。
如果我们使用await Promise作为延迟机制,那么我们就有机会在调用下一次迭代之前停止循环:
let stillGoing = true;
(async function foo() {
console.log('The quick brown fox did its thing');
await new Promise(resolve => setTimeout(resolve, 5000));
if (stillGoing) foo();
})();
foo();
在第二个示例中,我们首先设置5000ms的延迟,之后检查stillGoing值并决定是否调用另一个递归是合适的。
如果我们在任意点将stillGoing设为false,在我们设置值之后就不会打印出额外的log行。
需要注意的是,这要求函数是异步的,对于给定的使用,这可能是也可能不是一个选项。
其他回答
你可以将setInterval()包装在提供该行为的函数中:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
...然后这样使用它:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
这个例子建立在@Alnitak的回答上,但是使用await Promise在循环循环中进行更细粒度的控制。
比较的例子:
let stillGoing = true;
(function foo() {
console.log('The quick brown fox did its thing');
if (stillGoing) setTimeout(foo, 5000);
})();
foo();
在上面的例子中,我们调用foo(),然后它每5秒调用一次自己。
但是如果,在未来的某个时候,我们为了停止循环而将stillGoing设为false,即使在发出停止命令之后,我们仍然会得到一个额外的log行。这是因为在任何给定的时间,在我们将stillGoing设置为false之前,当前迭代将已经创建了一个超时来调用下一次迭代。
如果我们使用await Promise作为延迟机制,那么我们就有机会在调用下一次迭代之前停止循环:
let stillGoing = true;
(async function foo() {
console.log('The quick brown fox did its thing');
await new Promise(resolve => setTimeout(resolve, 5000));
if (stillGoing) foo();
})();
foo();
在第二个示例中,我们首先设置5000ms的延迟,之后检查stillGoing值并决定是否调用另一个递归是合适的。
如果我们在任意点将stillGoing设为false,在我们设置值之后就不会打印出额外的log行。
需要注意的是,这要求函数是异步的,对于给定的使用,这可能是也可能不是一个选项。
这里有一个简单的版本给新手,没有所有的混乱。它只是声明函数,调用它,然后开始interval。就是这样。
//在这里声明函数 函数My_Function () { console.log (" foo "); } //首先调用函数 My_Function (); //设置时间间隔 Var interval =窗口。setInterval(My_Function, 500);
在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));
}
})();
函数的即时异步调用存在一个问题,因为标准的setTimeout/setInterval即使直接将其设置为0,也具有大约几毫秒的最小超时。这是由浏览器特定的工作引起的。
一个具有REAL零延迟的代码示例,可在Chrome, Safari, Opera中工作
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
你可以在这里找到更多信息
在第一次手动调用之后,您可以用函数创建一个间隔。
推荐文章
- 一元加/数字(x)和parseFloat(x)之间的区别是什么?
- angularjs中的compile函数和link函数有什么区别
- 删除绑定中添加的事件监听器
- 很好的初学者教程socket.io?
- HtmlSpecialChars在JavaScript中等价于什么?
- React: 'Redirect'没有从' React -router-dom'中导出
- 如何在React中使用钩子强制组件重新渲染?
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 我如何等待一个承诺完成之前返回一个函数的变量?
- 在JavaScript中根据键值查找和删除数组中的对象
- 使嵌套JavaScript对象平放/不平放的最快方法
- 如何以及为什么'a'['toUpperCase']()在JavaScript工作?
- 有Grunt生成index.html不同的设置
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?