javaScript中的setTimeout无法正常工作

时间:2017-07-20 12:21:22

标签: javascript settimeout

我知道这有答案但是!!所有答案在循环中仅包含一个setTimeout此问题看起来与我相关How do I add a delay in a JavaScript loop? 但是在我的场景中我在脚本中有两个setTimeout,如何在时间上正确实现!该程序正常工作,但我想要的时间不正确!!!

function clickDate(i)
{
  setTimeout((function(){
  alert("4");
  })(),2000);
}
function clickButton(i)
{
  setTimeout((function(){
  alert("5");
})(),4000);
}

function doEverything(i)
{
  clickDate(i);
  clickButton(i);
}
for(var i = 0; i < 4; i++)
{
 doEverything(i);
}

5 个答案:

答案 0 :(得分:7)

当您将该函数传递给setTImeout时,您会立即调用该函数。删除额外的括号。

function clickDate(i)
{
  setTimeout(function(){
  alert("4");
  },2000);
}
function clickButton(i)
{
  setTimeout(function(){
  alert("5");
},4000);
}

function doEverything(i)
{
  clickDate(i);
  clickButton(i);
}
for(var i = 0; i < 4; i++)
{
 doEverything(i);
}

编辑

有点不清楚,当你将i传递给你的函数时,你希望你的代码到底是什么,我假设你想以某种方式使用它。目前,您正在创建一次性全部启动的超时。如果您希望它们按顺序启动,您需要错开延迟时间。通过将延迟时间乘以i+1,下面的代码每2秒记录一次“4”,每“4”秒记录一次“5”。

// Currently this code displays a 4 every 2 seconds and a 5 every 4 seconds
function clickDate(i)
{
  setTimeout(function(){
  console.log("4");
  },2000 * (i+1));
}
function clickButton(i)
{
  setTimeout(function(){
  console.log("5");
},4000 * (i+1));
}

function doEverything(i)
{
  clickDate(i);
  clickButton(i);
}
for(var i = 0; i < 4; i++)
{
 doEverything(i);
}

答案 1 :(得分:1)

您好我认为您还没有阅读有关javascript的文档。 它是异步的,它不会等待事件并继续该过程。我会给出答案,但我强烈建议您阅读有关Javascript的内容,只有在这里您才会遇到时间问题,因为您的两个函数将同时被调用。让我举个例子。

function clickDate(i,callback)
{
  setTimeout(function(){
  alert("4");
  callback();//this will call anonymous function in doEverything
  },2000);
}
function clickButton(i)
{
  setTimeout(function(){
  alert("5");
},4000);
}

function doEverything(i)
{
  console.log("In loop index is " , i);
  clickDate(i,function(){
       clickButton(i);
  });
  //look closely here I have passed the function in changeData and will call that funtion from clickDate
  console.log("In loop terminating index is " , i);
}
for(var i = 0; i < 4; i++)
{
 doEverything(i);
}
  

所以这里的控制台日志会让你清楚异步   功能。你将看到for循环终止,因为它继续   这是工作,并在第一次警报之前在2秒内完成   for循环将完成它的迭代。

希望这会有所帮助。

答案 2 :(得分:0)

您通过将()添加到函数末尾来立即调用回调。

你需要通过超时传递回调,它将为你打电话

setTimeout(function(){
alert('hello');
} , 3000);

答案 3 :(得分:0)

PXYXYXYXYXYXYXXYXXY 
XYXYXYXYXY 
1.828 
1.44928000 
1.20000000 
XYXYX 
XYXYX 
XYXY 
10096247566 


PXYXYXYXYXZZYXXYXXY 
XYZZYXYXYXY 
1.528 
1.45928000 
1.70000000 
XYXYX 
XYXYX 
XYXY 
10096247566 

..... 

试试这个。

答案 4 :(得分:0)

您使用setTimeout在JavaScript中模拟异步行为的方法是一种相对常见的做法。但是,为每个函数提供自己的setTimeout调用是一种反模式,仅由于JavaScript本身的异步特性,该模式才对您不利。 setTimeout似乎迫使JS以同步方式运行,因此生成了4 4 4 4然后5 5,您会通过for循环的迭代看到警报。实际上,JS仍然是异步运行的,但是因为您已经使用回调定义了多个setTimeout实例,这些回调被定义为匿名函数,并且在各自的函数范围内作为附件;您正在将JS异步行为的控制权从自己身上封装起来,这迫使setTimeout严格以同步方式运行。 作为使用setTimeout时处理回调的另一种方法,首先创建一个提供您希望发生的定时延迟的方法。示例:

// timer gives us an empty named "placeholder" we can use later
// to reference the setTimeout instance. This is important because
// remember, JS is async. As such, setTimeout can still have methods
// conditionally set to work against it.

let timer 

// "delayHandler", defined below, is a function expression which when
// invoked, sets the setTimeout function to the empty "timer" variable
// we defined previously. Setting the callback function as the function 
// expression used to encapsulate setTimeout provides extendable control
// for us later on however we may need it. The "n" argument isn't necessary,
// but does provide a nice way in which to set the delay time programmatically
// rather than hard-coding the delay in ms directly in the setTimeout function
// itself.

const delayHandler = n => timer = setTimeout(delayHandler, n)

然后,定义旨在用作事件处理程序的方法。附带说明一下,为帮助防止您的JS代码快速混乱,请将事件处理程序方法包装在一个主要的父函数中。一种(老派的)方法是利用JS Revealing Module Pattern。示例:

const ParentFunc = step => {

  // "Private" function expression for click button event handler.
  // Takes only one argument, "step", a.k.a the index
  // value provided later in our for loop. Since we want "clickButton"
  // to act as the callback to "clickDate", we add the "delayHandler"
  // method we created previously in this function expression.
  // Doing so ensures that during the for loop, "clickDate" is invoked
  // when after, internally, the "clickButton" method is fired as a
  // callback. This process of "Bubbling" up from our callback to the parent
  // function ensures the desired timing invocation of our "delayHandler"
  // method. It's important to note that even though we are getting lost
  // in a bit of "callback hell" here, because we globally referenced 
  // "delayHandler" to the empty "timer" variable we still have control
  // over its conditional async behavior.

  const clickButton = step => {
    console.log(step)
    delayHandler(8000)
  }

  // "Private" function expression for click date event handler
  // that takes two arguments. The first is "step", a.k.a the index
  // value provided later in our for loop. The second is "cb", a.k.a
  // a reference to the function expression we defined above as the
  // button click event handler method.

  const clickDate = (step, cb) => {
    console.log(step)
    cb(delayHandler(8000))
  }

  // Return our "Private" methods as the default public return value
  // of "ParentFunc"

  return clickDate(step, clickButton(step))
}

最后,创建for循环。在循环中,调用“ ParentFunc”。这将启动setTimeout实例,并将在每次循环运行时运行。示例:

 for(let i = 0; i < 4; i++) {

   // Within the for loop, wrap "ParentFunc" in the conditional logic desired
   // to stop the setTimeOut function from running further. i.e. if "i" is 
   // greater than or equal to 2. The time in ms the setTimeOut was set to run
   // for will no longer hold true so long as the conditional we want defined
   // ever returns true. To stop the setTimeOut method correctly, use the 
   // "clearTimeout" method; passing in "timer", a.k.a our variable reference 
   // to the setTimeOut instance, as the single argument needed to do so.   
   // Thus utilizing JavaScript's inherit async behavior in a "pseudo" 
   // synchronous way.

   if(i >= 2) clearTimeout(timer)
   ParentFunc(i)
 }

最后一点,尽管实例化setTimeOut是模拟异步行为的常见做法,但是在处理最初的调用/执行以及打算用作事件处理程序的方法的所有后续生命周期计时时,应遵循Promises的规定。使用Promises来解决事件处理程序,可以确保方法的执行时间与调用它们的场景有关,而不仅限于“ setTimeOut”方法中定义的严格计时行为。