javascript - 使用随机数生成器进行循环超时
问题描述
此脚本应以随机生成的延迟滚动浏览网站上的每个容器。对于循环中的每次迭代,我想2000
用随机生成的数字替换 ms的“暂停”。min
max
var min = 3,
max = 9;
var y = document.querySelectorAll('.chunk-container').length;
for (let x=0; x<y; x++) {
task(x);
}
function task(x) {
// var z = randomGen() * 1000;
setTimeout(function() {
console.log('X = ' + x + ' Y = ' + y);
document.getElementsByClassName('chunk chunk-container')[x].scrollIntoView({behavior: 'smooth'});
console.log('Scrolled to next Container');
}, /* z */ 2000 * x);
}
})
随机数发生器:
function randomGen() {
var rand = Math.floor(Math.random() * (max - min + 1) + min);
console.log('Random Number generated: ' + rand + ' seconds');
return rand;
}
像这样它工作正常。每次迭代后,会有 2 秒的暂停。但是,当我删除注释以添加行var z = randomGen() * 1000;
以随机化每次迭代之间的时间时,x
值(它应该滚动到哪个容器)开始时很好,但结果也是随机的。
控制台输出:
Random Number generated: 6 seconds
Random Number generated: 5 seconds
Random Number generated: 4 seconds
Random Number generated: 8 seconds
Random Number generated: 4 seconds
Random Number generated: 8 seconds
X = 0 Y = 7
Scrolled to next Container
X = 1 Y = 7
Scrolled to next Container
X = 2 Y = 7
Scrolled to next Container
X = 4 Y = 7
Scrolled to next Container
X = 3 Y = 7
Scrolled to next Container
X = 5 Y = 7
Scrolled to next Container
X = 6 Y = 7
Scrolled to next Container
我怎样才能解决这个问题?
解决方案
问题是2000 * x
因为每次滚动之间的延迟是恒定的,所以你的超时触发在:
x = 0
-> 0 毫秒x = 1
-> 2000 毫秒x = 2
-> 4000 毫秒
因此,您在开始时立即启动所有超时,它们最终每 2 秒触发一次,但每个超时的值是不同的。每个都隐含地取决于之前的所有超时都每 2 秒触发一次这一事实。
一种方法是使用异步函数,该函数返回一个承诺,await
并在滚动到下一个元素之前为它返回,正如Josh 指出的那样
另一种方法是跟踪先前的超时值并将它们相加,以计算下一个超时值。像这样:
var min = 3,
max = 9;
var y = document.querySelectorAll('.chunk-container').length;
for (let x=0, accumulatedDelay = 0; x<y; x++) {
accumulatedDelay += task(x, accumulatedDelay);
}
function task(x, accumulatedDelay) {
const z = randomGen() * 1000;
setTimeout(function() {
console.log('X = ' + x + ' Y = ' + y);
document.getElementsByClassName('chunk chunk-container')[x].scrollIntoView({behavior: 'smooth'});
console.log('Scrolled to next Container');
}, z + accumulatedDelay);
return accumulatedDelay;
}
推荐阅读
- sql-server-2008 - SSIS - 对连接管理器的 AcquireConnection 方法调用
- c++ - 如何用随机数填充我的二维数组?
- swift - 如何快速点击标签?
- vb.net - 序列化经常导致 VB.Net 中的内存不足问题
- haskell - Liquid Haskell:来自内联递归函数的“循环类型别名定义”错误
- java - 阅读 XBRL 事实 - Java
- html - Excel VBA从企业网络中的网页获取数据
- ruby-on-rails - 如何使用 Rails 中的条件在 has_many 上仅加入一条记录?
- ios - IONIC 3 - 底部标签 iPhone X UI 问题
- javascript - 如何为 webpack 配置提供自定义路径