【问题标题】:Javascript Loop & setIntervalJavascript 循环和 setInterval
【发布时间】:2011-03-24 08:32:55
【问题描述】:

这个js会取一个值,减去X的数量,然后计数到那个值。

我试图通过执行一个简单的 while 循环来完成这项任务,但我无法让它工作。

我想知道是否有人可以评论下面的 while 循环方法如何或为什么不起作用。

这是我让它工作的唯一方法:

function _initCountUpUsers()
{
    var totalUsers = $('#totalUsers');
    var ceiling = parseInt(totalUsers.html());
    var floor = ceiling - 10;

    function updateTotalUsers()
    {
        if(floor < ceiling)
        {
            totalUsers.html(floor);
            floor++;
        }
    }

    window.setInterval(updateTotalUsers, 1000, floor);
}

不工作的 While 方法:

function _initCountUpUsers()
{
    var totalUsers = $('#totalUsers');
    var ceiling = parseInt(totalUsers.html());
    var floor = ceiling - 10;

    function updateTotalUsers()
    {
        totalUsers.html(floor);
        floor++;
    }

    while(floor < ceiling)
    {
         window.setInterval(updateTotalUsers, 1000, floor);       
    }

}

【问题讨论】:

  • 我之所以想探索while(甚至是for)循环方法,是因为我认为它会是更好的实践或更学术的做事方法。
  • 它会更干净,但它并不真正可行。幸运的是,JavaScript 非常灵活 - 您可能会想出一些看起来更接近您想要的东西(请参阅我的更新答案)。

标签: javascript jquery while-loop setinterval


【解决方案1】:

我不知道你为什么不想坚持你的第一种方法,但是......

while(floor < ceiling)
{
     window.setInterval(updateTotalUsers, 1000, floor);       
}

这将启动 10 个独立的计时器,每个计时器设置为每秒触发一次,每个计时器设置为递增 floor 并更新 totalUsers,并且它们都不会终止。如果他们开火,您会看到计数每秒增加 10,而在第一个示例中增加 1。但是,它们都不会真正触发,因为您将永远循环等待 floor 到达 ceiling

JavaScript 是单线程的。事件(包括计时器)在脚本执行时排队。因此,您的 while 循环将永远不会终止,因为将更新它的计时器事件将等待触发,直到它完成执行!

即使不是这样,你仍然有十个计时器,每个计时器都永远运行。

您的第一种方法是正确的。你只需要停止计时器:

function _initCountUpUsers()
{
    var totalUsers = $('#totalUsers');
    var ceiling = parseInt(totalUsers.html());
    var floor = ceiling - 10;

    function updateTotalUsers()
    {
        if(floor < ceiling)
        {
            totalUsers.html(floor);
            floor++;
        }
        else
        {
          window.clearInterval(timerID); // stop firing the timer once per second
        }
    }

    var timerID = window.setInterval(updateTotalUsers, 1000, floor);
}

如果您正在寻找更简洁/不易出错的编写方式,只需编写一个小辅助例程即可:

function while_interval(proc, int)
{
  var timerID = setInterval(function()
  {
    if ( !proc() ) clearInterval(timerID);
  }, int);
}

...然后这样称呼它:

while_interval(function()
{
  if (floor < ceiling)
  {
    totalUsers.html(floor);
    floor++;
    return true;
  }
}, 1000);

这可以让你抽象出一点点管家代码,但更重要的是,只要你希望间隔循环继续执行,它就会迫使你有意识地返回true

【讨论】:

  • 你帖子底部的好例程,我已经复制/粘贴了它 - 但有一个错误:你说“clearTimer(timerID);”它应该是“clearInterval(timerID);”
  • 谢谢@Andy!多年后,终于有人注意到了——修复了!顺便说一句,请不要犹豫,提出更正此类琐碎错误的修改建议。
【解决方案2】:
function _initCountUpUsers()
{
    var totalUsers = $('#totalUsers'),
        ceiling = parseInt(totalUsers.html()),
        floor = cieling - 10,
        intRef = null;

    function updateTotalUsers()
    {
        if(floor < ceiling)
        {
            totalUsers.html(floor);
            floor++;
        }
        else {
            window.clearInterval(intRef);
        }
    }

    intRef = window.setInterval(updateTotalUsers, 1000);
}

function _initCountUpUsers()
{
    var totalUsers = $('#totalUsers');
    var ceiling = parseInt(totalUsers.html());
    var floor = cieling - 10;
    var int;

    function updateTotalUsers()
    {
        if(floor < ceiling)
        {
            totalUsers.html(floor);
            floor++;
            window.setTimeout(updateTotalUsers, 1000);
        }
    }

    window.setTimeout(updateTotalUsers, 1000);
}

【讨论】:

  • 是的,这就是他所说的有效方法......如果你要切换到 setTimeout,可能值得添加额外的代码来调整计时器延迟。
猜你喜欢
  • 2020-10-11
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多