首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要延迟javascript的执行,但事实证明setTimeout是有问题的

需要延迟javascript的执行,但事实证明setTimeout是有问题的
EN

Stack Overflow用户
提问于 2011-05-31 06:44:34
回答 4查看 1.3K关注 0票数 1

谢谢你抽出时间来帮我。

我正在写一个游戏,一个动画火车图标沿着给定的路径移动到目的地,中途停在路点上。这是为了给人动画的印象。

游戏是在Facebook Javascript中编码的。我需要找到一种方法,使火车图标暂停1秒,然后再前进到下一个路标点。我希望找到一个函数,允许我暂停脚本执行一秒钟,但在JS中似乎没有类似的东西。所以我尝试了setTimeout,但是我的主要问题是两个方面:

  1. --我需要将数组作为参数传递到回调函数中,但我不知道如何使setTimeout做到这一点。
  2. --我终于成功地使用setTimeout执行了5点的火车动画代码(我通过使用全局变量在1中克服了这个问题)。不幸的是,对setTimeout的所有五个调用似乎几乎同时排队,这导致等待第一个setTimeout启动的一秒,然后他们都立即开火,破坏了火车动画的错觉。

我已经和这个问题斗争了六个小时了。如果有人能帮我找到解决办法,那就太好了。谢谢!

下面是代码:

代码语言:javascript
复制
function myEventMoveTrainManual(evt, performErrorCheck) {
      if(mutexMoveTrainManual == 'CONTINUE') {
        var ajax = new Ajax();
        var param = {};
        if(evt) {
          var cityId = evt.target.getParentNode().getId();
          var param = { "city_id": cityId };
        }
        ajax.responseType = Ajax.JSON;
        ajax.ondone = function(data) {
            var actionPrompt = document.getElementById('action-prompt');
            actionPrompt.setInnerXHTML('<span><div id="action-text">'+
              'Train en route to final destination...</div></span>');
            for(var i = 0; i < data.length; i++) {
              statusFinalDest = data[i]['status_final_dest'];
               //pause(1000);
               gData = data[i];
               setTimeout(function(){drawTrackTimeout()},1000);
              if(data[i]['code'] == 'UNLOAD_CARGO' && statusFinalDest == 'ARRIVED') {
                unloadCargo();
              } else if (data[i]['code'] == 'MOVE_TRAIN_AUTO' || data[i]['code'] == 'TURN_END') {
                //moveTrainAuto();
              } else {
                // handle error 
              }
              mutexMoveTrainManual = 'CONTINUE';
            }  
        }
        ajax.post(baseURL + '/turn/move-train-final-dest', param);
      }

}


function drawTrackTimeout() {
  var trains = [];
  trains[0] = gData['train'];
  removeTrain(trains);
  drawTrack(gData['y1'], gData['x1'], gData['y2'], gData['x2'], '#FF0', trains);
  gData = null;
}
EN

回答 4

Stack Overflow用户

发布于 2011-05-31 06:56:44

通常,这将通过创建一个拥有所有数据和方法的对象(例如myTrain)来完成,然后调用一个myTrain.run方法来查看火车的位置。如果它位于两个站之间,它会用setTimeout自打电话,说延迟了50‘s。当它到达一个站时,它会以1000毫秒的速度呼叫自己,在车站产生1秒的停顿。

如果您同时对setTimeouts进行排队,则可能所有这些进程都会被其他进程延迟,然后所有这些进程都会同时运行。

嘿,有点好玩(小心包装)。需要通过良好的ole原型继承来进行一些实践:

代码语言:javascript
复制
<!-- All the style stuff should be in a rule -->
<div style="position: relative; border: 1px solid blue;">
  <div id="redTrain"
   style="width:10px;height:10px;background-color:red; position:absolute;top:0px;left:0px;"></div>
</div>

<script type="text/javascript">

// Train constructor
function Train(id) {
  this.element = document.getElementById(id);
  this.timerId;
}

// Methods
// Trivial getPos function
Train.prototype.getPos = function() {
  return this.element.style.left;
}

// Trivial setPos function
Train.prototype.setPos = function(px) {
  this.element.style.left = parseInt(px,10) + 'px';
}

// Move it px pixels to the right
Train.prototype.move = function(px) {
  this.setPos(px + parseInt(this.getPos(),10));
}

// Recursive function using setTimeout for animation
// Probably should accept a parameter for lag, long lag
// should be a multiple of lag
Train.prototype.run = function() {

  // If already running, stop it
  // so can interrupt a pause with a start
  this.stop();

  // Move the train
  this.move(5);

  // Keep a reference to the train for setTimeout
  var train = this;

  // Default between each move is 50ms
  var lag = 50;

  // Pause for 1 second each 100px
  if (!(parseInt(this.getPos(),10) % 100)) {
    lag = 1000;
  }

  train.timerId = window.setTimeout( function(){train.run();}, lag);

}

// Start should do a lot more initialising
Train.prototype.start = function() {
  this.run();
}

// Stops the train until started again
Train.prototype.stop = function() {
  if (this.timerId) {
    clearTimeout(this.timerId);
  }
}

// Set back to zero
Train.prototype.reset = function() {
  this.stop();
  this.setPos(0);
}

// Initialise train here
var myTrain = new Train('redTrain');

</script>
<p>&nbsp;</p>
<button onclick="myTrain.start();">Start the train</button>
<button onclick="myTrain.stop();">Stop the train</button>
<button onclick="myTrain.reset();">Reset the train</button>
票数 2
EN

Stack Overflow用户

发布于 2011-05-31 06:55:59

要传递参数,这可能会帮助您:

代码语言:javascript
复制
setTimeout(function() {
    (function(arg1, arg2) {
        // you can use arg1 / arg2 here
    })('something', 123);
}, 1000);

或者,如果使用定义的函数:

代码语言:javascript
复制
setTimeout(function() {
    someFunction('something', 123);
}, 1000);

它基本上启动了一个超时;1秒后,该函数将使用指定的参数调用。

票数 0
EN

Stack Overflow用户

发布于 2011-05-31 07:02:50

如何使用面向对象原则来简化问题?创建一个具有以下方法的"object“列车:

代码语言:javascript
复制
//train obj
function Train(){
   this.isOnWaypoint = function(){
     return calculateIsWayPoint()
   }

}

//main logic
var train = new Train()
var doneWaiting = false
var doneWaitingTimeout = undefined
var gameLoop = setInterval(1000,function(){
   ...
   if(train.isOnWaypoint() && !doneWaiting){
     if(doneWaitingTimeout == undefined){
       setTimeOut(5000,function(){
         doneWaiting = true
         doneWaitingTimeout = undefined
       })
     }
   }
   ...
})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6183904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档