【问题标题】:How to run setTimeout() with a random interval in each iteration in javascript?如何在javascript的每次迭代中以随机间隔运行setTimeout()?
【发布时间】:2021-12-04 22:32:40
【问题描述】:

我正在尝试迭代一个字符串数组,每一步迭代都有几毫秒的延迟。像下面这样 -

var l = ['a', 'b', 'c'];
var delay = 5000;
for(var i = 0;i < l.lenght;i++) {
    document.querySelectorAll("a[title='" + l[i] + "']")[0].parentNode.children[0].click();
    delay = 5000 + Math.floor(Math.random() * 5000) + 1;
   **<WAIT for 'delay' number of milliseconds**
}

我已经能够使用 setTimeout() 方法将代码转换为下面的代码 -

var i = 0;
var interval = setInterval(function() {
    if (i < l.length) {
        document.querySelectorAll("a[title='" + l[i] + "']")[0].parentNode.children[0].click();
       i++;
   }
   else {
      clearInterval(interval);
   }
   //delay = 5000 + Math.floor(Math.random() * 5000) + 1); **NOT SURE where to change the delay variable**
}, delay);

但是一旦 setTimeout 开始,延迟变量本质上就变成了一个常数。每次迭代如何改变延迟变量?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您可以尝试用这样的函数替换那个延迟变量吗?

    var i = 0;
    var interval = setInterval(
    function() {
      if (i < l.length) {
        document.querySelectorAll("a[title='" + l[i] + "']")[0].parentNode.children[0].click();
        i++;
      }
      else {
        clearInterval(interval);
      }
    },
    function() {
      return 5000 + Math.floor(Math.random() * 5000) + 1;
    }
    );
    

    【讨论】:

    • 谢谢。它会改变每次迭代的延迟吗?如果是这样,这可能是最简单的解决方案。我试试看。
    【解决方案2】:

    setInterval,您在示例中使用过,它会每(大约)N 毫秒初始化一个回调,其中 N 是固定的。您必须稍后使用clearInterval 清除它。

    setTimeout 另一方面意味着 - 在 ~N 时间后调用我的回调。然后,您可以在回调中调用另一个 setTimeout,使用不同的 N。

    举个例子:

    function callback() {
      /* 
        your logic here
      */
      delay = 5000 + Math.floor(Math.random() * 5000) + 1);
      setTimeout(callback, delay); // for your "clearInterval" case - just don't invoke this
    }
    
    setTimeout(callback, initialDelay);
    

    【讨论】:

    • 感谢您的解释。是的,我在示例中错误地提到了 setTimeout(),现在我发现我最初使用 setInterval() 的方法永远不会奏效。
    【解决方案3】:

    您可以为此创建一个递归计时器函数:

    尝试以下方法:

    function displayValue(){
      
      let arr = ['a', 'b', 'c'];
      let delay = 1000;  
      let i = 0;
      
      function timerFunction(i){
         if(i === arr.length)
          return;
          setTimeout(()=>{
            console.log(arr[i]);
            i++;
            timerFunction(i);
          }, delay);
          delay = delay + 1000 + Math.floor(Math.random() * 4000);
      } 
      
      timerFunction(i);
    }
    
    displayValue();

    【讨论】:

      【解决方案4】:

      这个线程似乎是我发现的最接近如何以随机时间间隔遍历数组的基本问题,这并不像人们想象的那么容易。 尽管对于所提出的特定问题可以说有点笼统,但当前接受的答案看起来与基本问题最接近。下面的代码是一个小的修改,它看起来在第一次传递时提供一个随机延迟,并在记录每个数组值之后记录每个随机延迟。

      function displayValue(){
      
          let arr = ['a', 'b', 'c','d', 'e'];
            let delay = Math.floor(Math.random()*10000);  
            let i = 0;
            
            function timerFunction(i){
               if(i === arr.length)
                return;
                setTimeout(()=>{
                  console.log(arr[i]);
                  console.log(`delay was ${Math.floor(delay/1000)} seconds`);
                  i++;
                  timerFunction(i);
                }, delay);
                delay = Math.floor(Math.random()*10000);
            } 
            
            timerFunction(i);
          }
          
          displayValue();
      

      上述修改的值可能取决于上下文。

      有趣的是,应用 bootcamp 中对 forEach 的介绍提供了一种替代解决方案,它可能与 OP 更相关!

      var colors = ["red", "green", "blue", "yellow"];
      
      function printArr(x){
          var random = Math.round(Math.random()*60000);
          setTimeout(() => {
              console.log(x);
              console.log(`Delay was ${Math.floor(random/1000)} seconds`)
          }, random);
      };
      colors.forEach(printArr);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-28
        • 2020-02-21
        • 2018-08-20
        • 2018-05-01
        • 2022-07-08
        • 1970-01-01
        • 2021-06-07
        相关资源
        最近更新 更多