使用随机数生成器实现循环超时
Using Random Number Generator for a Loop Timeout
此脚本应以随机生成的延迟滚动浏览网站上的每个容器。
我想用循环中每次迭代的 min
和 max
秒之间随机生成的数字替换 2000
毫秒的“暂停”。
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
我该如何解决这个问题?
我重写了你的代码。
我认为主要问题是 setTimeout
是非阻塞的。
我用promise
和await
一起解决了
function sleep(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
function randomGen(max, min) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
async function randomWaitAndScroll(elements, timeMin, timeMax) {
for (element of elements) {
let random = randomGen(timeMin, timeMax)
await sleep(random);
element.scrollIntoView({behavior: 'smooth'});
}
}
const containerElements = document.querySelectorAll('.chunk-container');
randomWaitAndScroll(containerElements, 3000, 9000);
问题是 2000 * x
有效,因为每次滚动之间的延迟是恒定的,所以您的超时触发时间:
x = 0
-> 0 毫秒
x = 1
-> 2000 毫秒
x = 2
-> 4000 毫秒
因此您在开始时立即启动所有超时,它们最终每 2 秒触发一次,但每个超时的值都不同。每个都隐含地取决于之前所有超时每 2 秒触发一次的事实。
一种方法是在滚动到下一个元素
之前使用一个异步函数,该函数 returns 一个承诺和 await
另一种方法是跟踪以前的超时值并将它们相加,以计算下一个超时值。像这样:
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;
}
此脚本应以随机生成的延迟滚动浏览网站上的每个容器。
我想用循环中每次迭代的 min
和 max
秒之间随机生成的数字替换 2000
毫秒的“暂停”。
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
我该如何解决这个问题?
我重写了你的代码。
我认为主要问题是 setTimeout
是非阻塞的。
我用promise
和await
一起解决了
function sleep(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
function randomGen(max, min) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
async function randomWaitAndScroll(elements, timeMin, timeMax) {
for (element of elements) {
let random = randomGen(timeMin, timeMax)
await sleep(random);
element.scrollIntoView({behavior: 'smooth'});
}
}
const containerElements = document.querySelectorAll('.chunk-container');
randomWaitAndScroll(containerElements, 3000, 9000);
问题是 2000 * x
有效,因为每次滚动之间的延迟是恒定的,所以您的超时触发时间:
x = 0
-> 0 毫秒x = 1
-> 2000 毫秒x = 2
-> 4000 毫秒
因此您在开始时立即启动所有超时,它们最终每 2 秒触发一次,但每个超时的值都不同。每个都隐含地取决于之前所有超时每 2 秒触发一次的事实。
一种方法是在滚动到下一个元素
await
另一种方法是跟踪以前的超时值并将它们相加,以计算下一个超时值。像这样:
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;
}