为数组中的一个一个数字设置超时 5 秒,但不是一次全部设置

Set time out 5 seconds for one by one number in array, but not for all at once

我有一个包含 100 个数字的数组,我想将活动 class 添加到其中的 20 个,那部分没问题并且可以工作。但是我想要每个数字之间的延迟。

我试过设置超时,但它一次只延迟所有数字 5 秒,但我想一个一个地设置活动 class,延迟 5 秒。请帮忙

function numbers() { 
                    
                        var activequantities;
                    activequantities = "@Html.DisplayFor(modelItem => item.Numbers)".split(",");
// this is array with sorted random numbers 20 of 100 example [22,33,46,57,etc]


                    function setClassNextItem(index)
{
    if (index >= activequantities.lenght) return;

    var value = activequantities[index];
    $(`.grid-container div[data-tabid=${value}]`).addClass('active');
    setTimeout(setClassNextItem(++index), 5000);
}

$(".grid-container div").removeClass('active');
                    setTimeout(setClassNextItem(0), 5000);

                        
                        
                }

<div class="grid-container">
        <div class="grid-item">

            <div class="grid-container2">
                <div class="grid-item2" data-tabid="1">1</div>
                <div class="grid-item2" data-tabid="2">2</div>
                <div class="grid-item2" data-tabid="3">3</div>
                <div class="grid-item2" data-tabid="4">4</div>
                </div>

一一添加活动class。每个数字之间有 5 秒的延迟。

尝试将 activequantities 转换为数字数组并执行如下操作:

function setClassNextItem(index)
{
    if (index >= activequantities.lenght) return;

    var value = activequantities[index];
    $(`.grid-container div[data-tabid=${value}]`).addClass('active');
    setTimeout(setClassNextItem(++index), 5000);
}

$(".grid-container div").removeClass('active');
setTimeout(setClassNextItem(0), 5000);

欢迎使用计算器!函数 setTimeout returns 一个将在 x 毫秒内解析的异步 Promise。如果你在循环中 运行 这个函数,你只需添加更多要解决的承诺,但它们都会在接近同一时间解决。例如:

发送第一个 Promise:它将等待 5 秒
一毫秒后,发送另一个将等待 5 秒的承诺
...
5 秒后,第一个 Promise 正确解析。
1 毫秒后,第二个承诺正确解析
...

此行为使您的所有 promise 几乎同时解析,仅在您初始化它们后 5 秒。

在你的例子中,因为你想以精确的时间间隔执行一个函数,你需要 setIntervalsetInterval 函数也需要一个 MS 时间和一个函数,但它每隔 x 毫秒重复这个函数,或者直到间隔以编程方式停止。例如:

var counting = 0;
var myInterval = setInterval(function() {
    //we do something...
    console.log('loop:' + counting ++);
    if(counting === 10) {
        // we do this 10 times, than we stop the interval
        clearInterval(myInterval);
    }
}, 1000);

这里我使用 1 秒间隔,因为 5 秒对于演示来说太长了。

遍历过滤后的元素数组并添加 (index + 1) * interval 回调超时以添加类名。

for (i = 0; i < 20; i++) {
  setTimeout(
    function (i) {
      //$this.addClass("active");
      console.log(`Add "active" class to element ${i}`);
    },
    (i + 1) * 1000, // shortened to 1 second for demo
    i
  );
}

是迄今为止最好和最简单的。另一种选择是走 async function/promise 路线。

/**
 * Time in milliseconds to wait between setting elements to active.
 */
const delayTime = 500, // shortened to half a second for the example
  $app = $('#app');

/**
 * Whether or not the routine is currently running.
 */
let stopped = true;

/**
 * Returns a promise that resolves after the specified number of milliseconds.
 */
function delay(ms) {
  return new Promise(res => setTimeout(res, ms));
}

function setActiveInSerial() {
  // a little user-friendly UI work
  stopped = !stopped;
  if (stopped) {
    $('#btn').text('Run');
  } else {
    $('#btn').text('Stop');
  }

  // promise that lets us serialize asynchronous functions
  let promise = Promise.resolve();

  $app.children().each(function() {
    promise = promise.then(async() => {
      if (stopped) {
        return;
      }

      $(this).addClass('active');

      // wait for `delayTime` to pass before resolving the promise
      await delay(delayTime);
      
      $(this).removeClass('active');
    })
  });
  
  // mark the routine as stopped and reset the button
  promise.then(() => {
    stopped = true;
    $('#btn').text('Run');
  });
}

// populate with items
for (let i = 1; i <= 20; i++) {
  $app.append($('<span>').text(`Item ${i}`));
}

// attach function to run button
$('#btn').click(setActiveInSerial);
#app {
  display: flex;
  flex-direction: column;
}

#app .active {
  background-color: cyan;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn">Run</button>
<div id="app"></div>

这段代码明显更长,但更灵活,是学习promises和async functions的好习惯。它的额外好处是不需要搜索元素的所有子元素以删除 active class.