在 JavaScript 中以预定义的不规则间隔调用函数
Call function at predefined irregular intervals in JavaScript
我必须 运行 在用户执行某些操作(如单击按钮)后的一些预定义的不规则间隔后编写一些代码。
间隔可以是 [1, 1.2, 2.05, 2.8, ...., 10.56]
、[0.2, 1.5, 3.9, 4.67, 6.8, .., 12.0]
或其他。因此,应在初始按钮单击后 1 秒、1.2 秒、2.05 秒等后调用该函数。
我如何在 JavaScript 中做到这一点?
您在一个函数中使用 setTimeout
,该函数被 调用 setTimeout
:
// intervals in seconds
const intervals = [1, 1.2, 2.05, 2.8, 10.56];
(function runIrregularly(runThisCode) {
if (intervals.length > 0) {
// get (and remove) the first element from the array:
const timeout = intervals.shift();
// and schedule the next call to run in the future
setTimeout(
() => runIrregularly(runThisCode),
timeout * 1000
);
}
// then run our real function
runThisCode();
})(doSomething);
function doSomething() {
console.log(Date.now());
}
现在,当我们使用 shift()
从数组的开头获取元素时,您应该在那个时候去“嗯,所以它甚至不关心它是一个数组吗?”事实上:因为这段代码不会迭代任何东西,你甚至可以用一个生成函数来替换它,这个生成函数会根据需要提供值:
function getNextInterval() {
// do whatever you like here
return some number;
}
(function runIrregularly(runThisCode) {
if (intervals.length > 0) {
const timeout = getNextInterval();
...
(如果你愿意,你甚至可以使用 generator function 来获得幻想)
此外,我们当然不必“像我们声明的那样”调用函数,我们也可以单独声明和使用它:
function runIrregularly(runThisCode) {
if (intervals.length > 0) {
...
}
runThisCode();
}
// and then at some later point in the code
runIrregularly(doSomething);
最后,如果你需要循环,而不是运行一次,我们可以结合shift
和push
,并在开始时复制间隔列表:
function runIrregularly(runThisCode, intervals) {
// get and remove the first element from the array
const timeout = intervals.shift();
// then push it back on as the last element.
intervals.push(timeout);
setTimeout(
() => runIrregularly(runThisCode, intervals),
timeout * 1000
);
runThisCode();
}
// and then later:
runIrregularly(doSomething, intervals.slice());
interval.slice()
是必要的,这样我们就可以保留原始数组的原始状态(否则用于其他函数将使它们不会在您的第一个间隔开始,而是“无论我们在循环中的哪个位置”基于然而许多电话是 运行ning)。
如何捕获和停止超时,我将作为练习留给 reader(web/SO 上有很多关于此的 questions/posts 可供查找)。
您也可以将 async/await 与 setTimeout 结合使用:
setTimeout(function() {
}, 1000);
将在 1 秒后执行函数。
您可以通过嵌套 setTimeout
调用(参见 Mike 的回答)或承诺 (async/await) 来实现您的目标:
function delayExecution(n) {
return new Promise((resolve) => {
setTimeout(resolve, n)
})
}
async function runIrregularly(fn, delays) {
for (const delay of delays) {
// suspend execution by `delay` amounts of seconds
await delayExecution(delay * 1000)
fn()
}
}
runIrregularly(() => {
console.log(Date.now(), "Hello")
}, [1, 2, 3])
我必须 运行 在用户执行某些操作(如单击按钮)后的一些预定义的不规则间隔后编写一些代码。
间隔可以是 [1, 1.2, 2.05, 2.8, ...., 10.56]
、[0.2, 1.5, 3.9, 4.67, 6.8, .., 12.0]
或其他。因此,应在初始按钮单击后 1 秒、1.2 秒、2.05 秒等后调用该函数。
我如何在 JavaScript 中做到这一点?
您在一个函数中使用 setTimeout
,该函数被 调用 setTimeout
:
// intervals in seconds
const intervals = [1, 1.2, 2.05, 2.8, 10.56];
(function runIrregularly(runThisCode) {
if (intervals.length > 0) {
// get (and remove) the first element from the array:
const timeout = intervals.shift();
// and schedule the next call to run in the future
setTimeout(
() => runIrregularly(runThisCode),
timeout * 1000
);
}
// then run our real function
runThisCode();
})(doSomething);
function doSomething() {
console.log(Date.now());
}
现在,当我们使用 shift()
从数组的开头获取元素时,您应该在那个时候去“嗯,所以它甚至不关心它是一个数组吗?”事实上:因为这段代码不会迭代任何东西,你甚至可以用一个生成函数来替换它,这个生成函数会根据需要提供值:
function getNextInterval() {
// do whatever you like here
return some number;
}
(function runIrregularly(runThisCode) {
if (intervals.length > 0) {
const timeout = getNextInterval();
...
(如果你愿意,你甚至可以使用 generator function 来获得幻想)
此外,我们当然不必“像我们声明的那样”调用函数,我们也可以单独声明和使用它:
function runIrregularly(runThisCode) {
if (intervals.length > 0) {
...
}
runThisCode();
}
// and then at some later point in the code
runIrregularly(doSomething);
最后,如果你需要循环,而不是运行一次,我们可以结合shift
和push
,并在开始时复制间隔列表:
function runIrregularly(runThisCode, intervals) {
// get and remove the first element from the array
const timeout = intervals.shift();
// then push it back on as the last element.
intervals.push(timeout);
setTimeout(
() => runIrregularly(runThisCode, intervals),
timeout * 1000
);
runThisCode();
}
// and then later:
runIrregularly(doSomething, intervals.slice());
interval.slice()
是必要的,这样我们就可以保留原始数组的原始状态(否则用于其他函数将使它们不会在您的第一个间隔开始,而是“无论我们在循环中的哪个位置”基于然而许多电话是 运行ning)。
如何捕获和停止超时,我将作为练习留给 reader(web/SO 上有很多关于此的 questions/posts 可供查找)。
您也可以将 async/await 与 setTimeout 结合使用:
setTimeout(function() {
}, 1000);
将在 1 秒后执行函数。
您可以通过嵌套 setTimeout
调用(参见 Mike 的回答)或承诺 (async/await) 来实现您的目标:
function delayExecution(n) {
return new Promise((resolve) => {
setTimeout(resolve, n)
})
}
async function runIrregularly(fn, delays) {
for (const delay of delays) {
// suspend execution by `delay` amounts of seconds
await delayExecution(delay * 1000)
fn()
}
}
runIrregularly(() => {
console.log(Date.now(), "Hello")
}, [1, 2, 3])