Javascript 每个循环中的settimeout有问题

Javascript 每个循环中的settimeout有问题,javascript,jquery,settimeout,each,Javascript,Jquery,Settimeout,Each,我试图循环一些值,它们是毫秒。我需要每隔xxxx秒运行一些代码,这取决于他从循环中获得的值,但我无法让它工作,虽然它工作,但它不能按时运行 代码包含一个重置按钮(代码来自插件,但我不得不修改它) //插件选项 step:[ { time: 6000, // more stuff here // but we dont need // it in this example },

我试图循环一些值,它们是毫秒。我需要每隔xxxx秒运行一些代码,这取决于他从循环中获得的值,但我无法让它工作,虽然它工作,但它不能按时运行

代码包含一个重置按钮(代码来自插件,但我不得不修改它)

//插件选项

  step:[
      {
          time: 6000,
          // more stuff here 
          // but we dont need 
          // it in this example
      },
      {
          time: 3000,
          // more stuff here 
          // but we dont need 
          // it in this example
      },
      {
          time: 12000,
          // more stuff here 
          // but we dont need 
          // it in this example
      }
  ]
//循环

  var timeouts = [];
  $.each(options.step, function(i, value){

      var time =  value.time;                                                       
      timeouts.push(setTimeout(function(){

          alert('some action');

      },time*i));

  });
//重置按钮

  $('.stop').click(function(){
      $.each(timeouts, function (_, id) {
          clearTimeout(id);
      });
      timeouts = [];
  })

我的主要猜测是您没有设置所需的计时器时间。您正在使用
i*value.time
作为计时器时间,这似乎很奇怪。您是否意识到
i
是数组的索引,所以第一次它将是零,然后是1,然后是2,等等

这将导致计时器时间为:
0*6000、1*3000、2*12000
,这将转换为
0、3000、24000

这似乎不是你想要的


此外,浏览器中的Javascript是单线程的(除了webWorkers和一些事件副作用,这些不是我们在这里讨论的)。因此,
setTimeout()
不保证准确。如果在触发计时器事件时正在运行其他事件,则该计时器事件将进入事件队列,并将在当前Javascript执行线程完成后运行。因此,
setTimeout()
如果在触发时有其他东西正在运行,则不会按时运行

您正在设置的间隔将是0秒(6000*0)、3秒(3000*1)和24秒(24000*2)。这是因为您要乘以索引(
i
)。这就是您试图达到的时间间隔吗?

time*i
-这可能是您的问题

以您提供的数据为例,您将获得以下时间:
6000
3000
12000

让我们将它们乘以
i
,得到
0
3000
24000

编辑: 正如下面评论中所建议的,您希望第一个值始终为零,结果值保持原样

将超时延迟设置为
i==0?0:时间将起作用

这基本上意味着
表达式?真:假


这里有一个例子:

如果我只在值上使用它,它会工作(这是我第一次使用的),但现在它有了不同的值。那么使用索引器是否会导致错误呢?如果没有,请以具体的时间间隔指定您试图实现的目标。我尝试每xxx秒运行一段代码(取决于值),如果我在示例中使用固定值10000,它将运行一段代码,并等待10秒再继续,然后运行一段代码,等待10秒等等。是的,索引不是正确的值,我想,不同的值也不一样。你不需要乘以索引器。删除该表达式(
time*i
)。您不需要
time
变量,因为闭包函数作用域:var timeouts=[];$。每个(options.step,函数(i,value){timeouts.push(setTimeout(函数(){alert('some action');},value.time));});不完全正确@BlakeRegalia-那篇文章与此上下文或OP的问题(例如
setTimeout()
)无关。只是说,在不承认具体情况的情况下,不要对JavaScript做出粗体、笼统的陈述是好的。感谢您编辑您的answer@BlakeRegalia-根据我所知道的单线程与多线程的定义,文章中描述的事件触发仍然是单线程的。没有两个javascript线程同时执行。由于调用
.focus()
,某些事件处理程序可能会运行,这一事实类似于同步函数调用。它不是多线程的。如果您的代码设计不好,需要注意,但仍然是单线程的,那么它可能会导致问题。当然,整个问题与
setTimeout()
触发的时间无关,只是不要乘以
i
。只需使用
time
。然后使用
i==0?0:时间不起作用,它看起来像是在继续之前循环值2