Javascript Loop & setInterval - PullRequest
       3

Javascript Loop & setInterval

2 голосов
/ 02 августа 2010

Этот 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);
}

нерабочий метод Метод:

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);       
    }

}

Ответы [ 2 ]

3 голосов
/ 02 августа 2010

Я не уверен, почему вы не хотели придерживаться своего первого метода, но ...

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

Это будет запускать 10 отдельных таймеров, каждыйустанавливается для запуска один раз в секунду, каждый из которых устанавливается на floor и обновляет totalUsers , и ни один из них никогда не завершается.Если бы они стреляли, вы бы увидели, что количество увеличивается на десять каждую секунду, по сравнению с одним в вашем первом примере.Тем не менее, ни один из них на самом деле не сработает, поскольку вы будете зацикливаться вечно, ожидая, пока этаж достигнет потолок !

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++;
        }
<b>        else
        {
          window.clearInterval(timerID); // stop firing the timer once per second
        }</b>
    }

    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 столько, сколько вы хотитеинтервал цикла, чтобы продолжить выполнение.

0 голосов
/ 02 августа 2010
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);
}
...