javaScript中的setTimeout无法正常工作

javaScript中的setTimeout无法正常工作,javascript,settimeout,Javascript,Settimeout,我知道有答案,但是!!所有答案在循环中只包含一个setTimeout。这个问题看起来与我有关 但是在我的场景中,脚本中有两个setTimeout,如何通过计时正确地实现它!!程序运行正常,但我想要的时间不正确 function clickDate(i) { setTimeout((function(){ alert("4"); })(),2000); } function clickButton(i) { setTimeout((function(){ alert("5");

我知道有答案,但是!!所有答案在循环中只包含一个setTimeout。这个问题看起来与我有关 但是在我的场景中,脚本中有两个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);
}
功能点击日期(一)
{
setTimeout((函数(){
警报(“4”);
})(),2000);
}
功能点击按钮(一)
{
setTimeout((函数(){
警报(“5”);
})(),4000);
}
功能做任何事情(i)
{
点击日期(i);
点击按钮(一);
}
对于(变量i=0;i<4;i++)
{
做任何事(我);
}

将函数传递给setTImeout时,您将立即调用该函数。去掉额外的括号

功能点击日期(一)
{
setTimeout(函数(){
警报(“4”);
},2000);
}
功能点击按钮(一)
{
setTimeout(函数(){
警报(“5”);
},4000);
}
功能做任何事情(i)
{
点击日期(i);
点击按钮(一);
}
对于(变量i=0;i<4;i++)
{
做任何事(我);

}
您好,我想您还没有阅读有关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);
}
函数clickDate(i,回调)
{
setTimeout(函数(){
警报(“4”);
callback();//这将调用doEverything中的匿名函数
},2000);
}
功能点击按钮(一)
{
setTimeout(函数(){
警报(“5”);
},4000);
}
功能做任何事情(i)
{
log(“循环内索引为”,i);
单击日期(i,函数(){
点击按钮(一);
});
//仔细看这里,我已经在changeData中传递了函数,并将从clickDate开始调用该函数
log(“循环终止索引为”,i);
}
对于(变量i=0;i<4;i++)
{
做任何事(我);
}
所以这里的控制台日志将使您清楚地了解异步 功能。您将看到for循环在继续时终止 它的工作,很容易在2秒钟内完成,所以在您的第一个警报 for循环将完成它的迭代


希望这会有所帮助。

通过在函数末尾添加
()
立即调用回调

您需要通过带有超时的回调,它将为您调用

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

试试这个。

用setTimeout模拟JavaScript中的异步行为是一种比较常见的做法。然而,为每个函数提供其自己的setTimeout调用是一种反模式,这仅仅是由于JavaScript本身的异步性质而对您不利。setTimeout可能看起来像是在强迫JS以同步的方式运行,从而生成您在for循环的迭代中看到的4 then 5警报。实际上,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)
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(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)
 }
然后,定义用作事件处理程序的方法。作为旁注,为了避免JS代码迅速变得混乱,请将事件处理程序方法包装在一个主父函数中。一种(传统的)方法是利用JS模块模式。例如:

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实例,并将在每次运行循环时运行。例如:

// 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)
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(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)
 }
for(设i=0;i<4;i++){
//在for循环中,将“ParentFunc”换行到所需的条件逻辑中
//停止setTimeOut函数进一步运行。例如,如果“i”为
//大于或等于2。setTimeOut设置为运行的时间(毫秒)
//因为只要我们想要定义的条件,它就不再成立
//ever返回true。要正确停止setTimeOut方法,请使用
//“clearTimeout”方法;传入“timer”,即我们的变量引用
//到setTimeOut实例,作为执行此操作所需的单个参数。
//因此,在“伪”模式中利用JavaScript的继承异步行为
//同步方式。
如果(i>=2)清除超时(计时器)
ParentFunc(一)
}

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

仔细查看回调使用的语法。它与您链接到的帖子中使用的函数不同。不要使用
(function(){alert(“5”);})(
),因为它是一个立即执行的函数,一旦代码到达就会执行,并将结果作为回调传递。使用
function(){alert(“5”);}
好的,我正在使用回调函数按45454545的顺序发出警报,但如果不使用回调函数,我将得到4445,然后是5555。这也会有计时问题。您的答案解决了计时问题,但警报不同步!!输出是4 4 4,然后是5 5 5。OP不清楚他想要代码做什么,所以我尽量不要假设太多。然而,使用alert是一个坏主意,因为它不能让您很好地了解