循环中的 setTimeout。如何获得正确的订单
Posted
技术标签:
【中文标题】循环中的 setTimeout。如何获得正确的订单【英文标题】:setTimeout in a loop. How to get the correct order 【发布时间】:2020-11-17 00:57:23 【问题描述】:我试图在循环中调用一个函数以实现不同的超时或延迟。
for (var i = 0; i < 10; i++)
callDelayedFunction(i);
function callDelayedFunction(i)
setTimeout(function ()
console.log(i);
, getRandomInt(1500, 4500) * i);
我期待
1,2,3,4,5,6,7,8,9
但我明白了
1,2,3,4,7,8,5,6,9
我该如何解决这个问题?
【问题讨论】:
你需要使用链式承诺 您的超时是随机的,因此它们以随机顺序触发也就不足为奇了。我不确定我明白你在问什么。 @RobinZigmond 我半信半疑他要求 ti 随机等待 1 时间,然后随机等待 2 时间,然后随机等待 3时间量 哦,好的,这是一个合理的假设 - 谢谢@TKoL(在这种情况下我当然同意你的回答)。 【参考方案1】:这是一种方法,使用async
/await
:
function callDelayedFunction(i)
return new Promise(resolve =>
setTimeout(function()
console.log(i);
resolve();
, getRandomInt(1500, 4500) * i);
)
function getRandomInt(min, max)
return Math.floor(Math.random() * (max - min)) + min;
async function run()
for (var i = 0; i < 10; i++)
await callDelayedFunction(i);
run();
【讨论】:
【参考方案2】:你不应该期望数字按顺序打印出来,如果你设置随机超时并且不采取任何步骤来保证第n+1次迭代在之后 /em> 第 n 次迭代。
在不改变范式的情况下,您可以通过引入这样的辅助变量来解决任务 - 每个下一个 setTimeout
都使用比前一个更大的延迟参数调用:
var timeoutLimit = 0;
function getRandomInt(low, high)
return Math.floor(Math.random() * (high - low) + low);
for (var i = 0; i < 10; i++)
callDelayedFunction(i);
function callDelayedFunction(i)
var delay = getRandomInt(150, 450) + 1;
timeoutLimit += delay;
setTimeout(function()
console.log(i);
, timeoutLimit);
【讨论】:
【参考方案3】:你可以试试这个。该代码在 3 秒窗口内选择了一个随机时间。这会根据索引值设置窗口。
for (var i = 0; i < 10; i++)
callDelayedFunction(i);
function callDelayedFunction(i)
let windowLength = 3000;
let startTime = 1500;
setTimeout(function ()
console.log(i);
, startTime + getRandomInt(windowLength*i, windowLength*(i+1)));
function getRandomInt(a, b)
return Math.floor((Math.random()*(b-a)) + a);
【讨论】:
以上是关于循环中的 setTimeout。如何获得正确的订单的主要内容,如果未能解决你的问题,请参考以下文章
js经典面试问题:如何让for循环中的setTimeout()函数像预想中一样工作?
如何确保所有使用redux的promise中的promise顺序正确?