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

问题描述 投票:0回答:2

我有100个数字的数组,我想向其中20个数字添加活动类,该部分可以正常工作。但是我想在每个数字之间延迟。

我尝试使用settimeout,但是一次只能将所有数字延迟5秒,但是我想将活动类一一设置为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>

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

javascript loops settimeout delay each
2个回答
1
投票

遍历过滤的元素数组并为回调添加(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
  );
}

0
投票

尝试将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);


0
投票

欢迎使用stackoverflow!函数setTimeout返回一个异步承诺,它将在x ms内解决。如果您循环运行此函数,则只需添加更多需要解决的承诺,但它们都将在接近同一时间解决。例如:

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

此行为使您的所有诺​​言几乎都在同一时间完成,仅在初始化诺言之后5秒钟。

在您的情况下,由于要以精确的间隔执行功能,因此需要setIntervalsetInterval功能在MS和一个功能中也要花费一些时间,但它每x ms重复一次此功能,或者直到间隔以编程方式停止为止。例如:

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个演示太长了。


0
投票

Drew's answer是迄今为止最好和最简单的方法。另一种选择是走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>

该代码显然更长,但更灵活,对于学习promise和异步函数是一个很好的实践。它的另一个好处是,无需搜索元素的所有子元素即可删除active类。

© www.soinside.com 2019 - 2024. All rights reserved.