使用setTimeout强制创建新元素之间的延迟

时间:2016-03-31 19:44:36

标签: javascript jquery html

我试图制作一个p然后有一个延迟,然后再做一个我的战斗功能,直到我尝试添加setTimeout。我尝试过使用setTimeout几乎无处不在。有时它会创建一个无限循环,并且在某些地方它可以在它同时创建每个p之前延迟。

效果应与此Click Attack Button

类似

我尝试使用与此codepen创建者相同的方法,但我不了解他的代码是如何工作的。

Here is the Demo

function timeout() {
  setTimeout(function() {

  }, 500);
}

var battle = function() {

  while (monsterHP > 0) {

    var playerDam = Math.floor(Math.random() * ((playerAtk - monsterAtk) + 2));

    var newP = $('#battle').append("<p>You have hit the monster for " + playerDam + " damage. The monster has " + (monsterHP - playerDam) + "HP left</p>");
    monsterHP -= playerDam;
    timeout();
    if (monsterHP <= 0) {
      $('#battle').append("<p>You have defeated the monster</p>");

    }
  }

}


$('#battleButton').click(function() {
  battle();
});

4 个答案:

答案 0 :(得分:1)

我试着在评论中解释,但它不合适,因为这里有几件事情。它只是修复它并讨论新代码更容易:

var battle = function() {
  var i=0;
  while (monsterHP > 0) {
    (function(hp){

    var playerDam = Math.floor(Math.random() * ((playerAtk - monsterAtk) + 2));
    monsterHP-= playerDam;

   hp= monsterHP; // this might or might not be needed.

   setTimeout(function(){
    var newP = $('#battle').append("<p>You have hit the monster for " + playerDam + " damage. The monster has " + (hp - playerDam) + "HP left</p>");
    if (hp<= 0)$('#battle').append("<p>You have defeated the monster</p>");
   }, i++ * 500);


   }(monsterHP));
  }
}

这里我已经将计算移到了循环的顶部,然后将setTimeout后面的计算的可见动作推迟了1/2秒。

您需要循环更改的变量的私有副本,并且您需要一个可以使用这些值的超时。

答案 1 :(得分:1)

您可以稍微更改一下您的战斗功能,而不是使用while循环,只需让setTimeout()调用为您循环。

以下是我对您的链接小提琴的修改示例:

var playerAtk = 5;
var playerDef = 5;
var playerHP = 10;
var monsterAtk = 4;
var monsterDef = 4;
var monsterHP = 8;

var battle = function() {
  if (monsterHP > 0)
  {
    var playerDam = Math.floor(Math.random() * ((playerAtk - monsterAtk) + 2));
    var newP = $('#battle').append("<p>You have hit the monster for " + playerDam + " damage. The monster has " + (monsterHP - playerDam) + "HP left</p>");
    monsterHP -= playerDam;
    setTimeout(function() {
      battle();
    }, 1000);
  }
  else {
    $('#battle').append("<p>You have defeated the monster</p>");
  }
}


$('#battleButton').click(function() {
  battle();
});

你可以看到我的JSFiddle here

答案 2 :(得分:0)

您遇到的问题是timeout的实施。正如评论中提到的tymeJV,setTimeout是异步的。您的代码不会停止它为完成超时所做的工作。相反,你必须传递回调以在时间结束时完成(在你的情况下附加元素)。

在您的控制台中尝试使用此代码段来更好地说明这一点:

setTimeout(function() {
  console.log('hello from callback');
}, 3000)

console.log('hello from outside');

正如您所看到的,即使在超时之后,后面的代码也会先运行。

答案 3 :(得分:0)

接受的解决方案并行启动了多个Boolean_error = [False True False True True False True False False False False False] Has_length = [True True True True False True True True True True True False] print Boolean_error[Has_length] >>> [False True False True False True False False False False] 次呼叫。在你的情况下,它往往会少于十几个并发计时器 - 虽然不能保证它会因为随机数而启动多少计时器。

在大多数情况下,让每个超时开始下一个超时更好,而不是像这样一次全部启动它们。例如,假设您需要报告比此更长的运行进程的定期进度,或者在程序退出之前一直保持运行的进程?您需要大量的并发超时。

这是您的代码的一个版本,与原始代码的更改很少,并且在任何时候只使用一个setTimeout(),以避免此问题。

它的工作方式很简单:它根本不使用循环,而是setTimeout()调用battle()如果它需要另一次运行。 timeout()会将timeout()作为参数传递给battle,因此会在时间过去时调用setTimeout()

我用battle()为您标记了更改:

//**

Working fiddle