【问题标题】:How do I restart settimeout when looping in an array for each array element在为每个数组元素循环数组时如何重新启动settimeout
【发布时间】:2021-08-08 04:35:11
【问题描述】:

我有以下数组。[{startColor:"red",event:"start",time:0.3},{stopColor:"blue",event:"stop",time:10},{startColor:"green",event:"start",time:40}]。我正在循环遍历数组,对于每个 settimeout 时间段,我想使用 settimeout 在每个数组元素的时间部分冻结该给定时间段的代码,并显示数组元素中秒数的相应颜色。 .例子 。对于每个数组元素 settimeout(function, time_from_the_element) 。我面临的挑战是,它正在循环,但在第一个元素被循环后, settimeout 不会为第二个元素重新启动。也就是说,假设第一个元素需要 14 秒,下一个元素需要 16 秒,因此在前 14 秒之后,只需要两秒即可调用下一个元素,尽管我希望在前 14 秒之后,settimeout 在 0 处重新开始,并且数到 16 再等等。我花了一整天的时间来尝试解决它。 我面临的另一个挑战是,在数组中的最后一个循环之后,我想从显示中清除最后一个元素的颜色。那是在最后一个元素被循环之后,这看起来很棘手。

注意:setClockBackgroucosetbackgroucol 是用于显示颜色的函数,在这种情况下可以用 console.log 替换。

 const changeColors = async () => {
        const dat2 = await new Promise((resolve) => {
          for (let i = 0; i < data.length; i++) {
            console.log("data i is:", data[i]);
            if (data[i].event === "start") {
              setTimeout(() => {
                console.log("Start: ", data[i].event);

            setClockBackgroucol(null);
            setbackgroucol(data[i].startColor);

          
          }, data[i].programtime * 1000);
        } else if (data[i].event === "stop") {
          setTimeout(() => {
            console.log("Stop: ", data[i].event);

            setClockBackgroucol(data[i].stopColor);
            setbackgroucol(null);

            console.log(
              "time taken is ",
              data[i].time. * 1000
            );
          }, data[i].time * 1000);
         
        }

        console.log("should have been called last");
     
      }
    });
  
  };

【问题讨论】:

    标签: javascript arrays loops settimeout


    【解决方案1】:

    试试这个方法

    async function changeColors() {
      const array = [
        { startColor: "red", event: "start", time: 3000 },
        { stopColor: "blue", event: "stop", time: 1000 },
        { startColor: "green", event: "start", time: 4000 },
      ];
      for (const object of array) {
        switch (object.event) {
          case "start": {
            console.log(object.startColor);
            await delay(object.time); // in milliseconds
            break;
          }
          case "stop": {
            console.log(object.stopColor);
            await delay(object.time); // in milliseconds
            break;
          }
          default:
            continue;
        }
      }
    }
    
    function delay(ms) {
      return new Promise((resolve) => setTimeout(resolve, ms));
    }
    changeColors()

    【讨论】:

    • 这是解决问题的好方法! delay(ms) 是一个功能完全符合其名称的功能:它将调用 (async!) 函数中的进一步操作延迟ms 毫秒。在我看来,应该在异步函数中进行最终调用,重置(或隐藏)最后一个颜色 for 循环完成之后。否则最后显示的颜色(绿色)将永远保留在那里,并且在分配的时间(4000 毫秒)后不会再次隐藏。
    • 哇!。对此感激不尽。它的作用只是在循环完成后不会重置最后一种颜色,在这种情况下,在 for 循环之后我立即调用函数将颜色设置为 null 以清除状态中的任何颜色。它工作得很好。再次感谢你
    【解决方案2】:

    这只是一个 sn-p(基于 @Pawan Bishnoi 的回答)来证明 switch 可以很容易地被一个简单的表达式替换,并且最终的“重置”调用将删除最后设置的颜色。否则,我认为 Pawan 创造了一个出色的答案,应该被选为“正确”的答案。

    async function changeColors() {
      const array = [
        { startColor: "red", event: "start", time: 300 },
        { stopColor: "blue", event: "stop", time: 10000 },
        { startColor: "green", event: "start", time: 4000 },
      ];
      for (const o of array) {
        console.log(o[o.event+"Color"]);
        await delay(o.time); // in milliseconds
      }
      console.log("no color");
    }
    
    function delay(ms) {
      return new Promise((resolve) => setTimeout(resolve, ms));
    }
    changeColors()

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 2013-07-20
      • 2018-01-22
      • 2017-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      相关资源
      最近更新 更多