【问题标题】:Setting A Callback Function To A Timer设置定时器的回调函数
【发布时间】:2017-03-29 03:39:59
【问题描述】:

我非常接近完成这个程序,但我无法弄清楚最后一个部分。我让我的网页连接到服务器以获取随机生成的数字,然后将其绘制到图表上。我需要设置它,以便它每 2 秒绘制一次数据点,我不知道如何设置我的 setInterval 命令。我可以让它与for 循环一起工作,但这显然不是定时的。当我将限制设置为超过某个阈值时,它也会崩溃,这可能表明尝试使用计时器时出现问题。我将发布我的代码以及我尝试过的一些事情。

代码优先:

function plotData(dataSet) 
{
var x = xScale+20; // 20 = margin length
var y = 260;    //origin of graph

context.strokeStyle="#0000FF";
context.beginPath();

for (i = 1; i <= 10; i++)
{
  getRequest(function(random)
  { 
    var diff = (dataSet[0]*100) - (dataSet[1] * 100);
    diff = diff/5;                                                          
    y = y+(diff*23);

    context.lineTo(x, y);
    context.moveTo(x, y);
    context.stroke();   

    x=x+xScale;
    console.log("dataSet = "+dataSet[0]+", "+dataSet[1]);
    dataSet[0] = dataSet[1];
  });   
}
}

我现在将其设置为循环以进行调试。

回调函数到达XMLHttpRequest 以获取随机数(如果需要,我也可以发布此代码)。

我试图做的是实现 setInterval 以及一些布尔值,以在第二次函数调用时停止该函数。

类似这样的:

var isRunning = false;

function plotData(dataSet) 
{
 if (isRunning == false)
 {
  isRunning = true;
 }

 if (isRunning == true)
 {
  isRunning = false;
  myTimer = clearInterval();
 }
var myTimer;
var x = xScale+20; // 20 = margin length
var y = 260;    //origin of graph

context.strokeStyle="#0000FF";
context.beginPath();

 while (isRunning == true)
 {
  myTimer = setInterval(function()
  { 
   getRequest(function(random)
   {    
    var diff = (dataSet[0]*100) - (dataSet[1] * 100);
    diff = diff/5;                                                          
    y = y+(diff*23);

    context.lineTo(x, y);
    context.moveTo(x, y);
    context.stroke();   

    x=x+xScale;
    console.log("dataSet = "+dataSet[0]+", "+dataSet[1]);
    dataSet[0] = dataSet[1];
   });
  }, 2000);

 }
}

我添加了一个全局布尔值isRunning 用于处理目的。

如果isRunning 之前为假(表明它现在正在进行中),我将它设置为真。

如果之前为真,我将isRunning 设置为假,然后转到clearInterval 以停止它。

最后设置一个while循环让回调函数执行whileisRunning == true

这一切只是让我的程序崩溃。在这种情况下如何正确使用setInterval函数?

【问题讨论】:

  • while (isRunning == true) { myTimer = setInterval(function() 你在循环的每次迭代中都添加了一个新的间隔......这段代码会锁定大多数浏览器
  • 好收获。这是将代码植入setInterval 函数的正确语法吗?
  • 刚刚检查过,这是正确的语法。感谢您的帮助!

标签: javascript ajax timer


【解决方案1】:

在传递给 setInterval() 的回调中执行检查 isRunning == true。试试这样的,

myTimer = setInterval(function(){
  if(isRunning == true) {
    /* clear the timer */
  }
  /* Else perform the request */
}, 2000)

isRunning 评估为真时,计时器将被清除,停止后续setInterval

【讨论】:

    【解决方案2】:

    可以使用 setTimeout 代替 setInterval。

    将有一个函数调用 XMLHttpRequest 并处理响应。在 XMLHttpRequest 的响应回调中以 setTimeout 调用此函数。这意味着下一个请求总是在最后一个响应(和最后一个绘图)之后 2 秒。这将避免使用标志来检查是否有正在进行的请求。

    function plotData(dataSet) {
      var x = xScale+20; // 20 = margin length
      var y = 260;    //origin of graph
    
      context.strokeStyle="#0000FF";
      context.beginPath();
    
      var counter = 10;
    
      function plotPoint() {
        getRequest(function(data) {
          var diff = (dataSet[0]*100) - (dataSet[1] * 100);
          diff = diff/5;
          y = y+(diff*23);
    
          context.lineTo(x, y);
          context.moveTo(x, y);
          context.stroke();   
    
          x = x + xScale;
          console.log("dataSet = "+dataSet[0]+", "+dataSet[1]);
          dataSet[0] = dataSet[1];
    
          if (counter-- > 0) {
            setTimeout(plotPoint, 2000);
          }
        }
      }
    
      plotPoint();
    }
    

    【讨论】:

    • setTimeout 不会解决这样一个事实,即一旦 while 循环中的条件为真,它就会永远为真,并锁定浏览器
    • 在这种情况下不会有 while 循环或标志。发送请求是异步的,所以所有的请求基本上是同时发送的。最好的方法是仅在第一个请求完成后发送下一个请求。
    • 抱歉,您以为您说的唯一更改是 setTimeout 而不是 setInterval - 我的错
    • 定时器设置的次数是预先知道的吗?他不是说使用 10 次迭代的 for 循环只是为了调试目的吗?我可能误解了这个问题,在这种情况下,您的答案就是需要做的事情。
    • 我可能误解了这一点。我相信无论如何都需要有一个停止条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多