Можете ли вы использовать setInterval для асинхронного вызова функций? - PullRequest
4 голосов
/ 17 февраля 2012

Следующий код взят из Project Silk (пример приложения Microsoft) Приведенный ниже метод публикации проходит через массив событий callBacks и выполняет каждый из них. Вместо использования цикла for вместо него используется setInterval.

В документации сказано, что это позволяет каждому обратному вызову подписчика вызываться до завершения предыдущего обратного вызова. Это правильно? Я думал, что браузер не разрешит выполнение функции внутри интервала до тех пор, пока не завершатся все предыдущие исполнения.

Действительно ли это отличается от цикла for?

that.publish = function (eventName, data) 
{
    var context, intervalId, idx = 0;
    if (queue[eventName]) 
    {
        intervalId = setInterval(function () 
        {
            if (queue[eventName][idx]) 
            {
                context = queue[eventName][idx].context || this;
                queue[eventName][idx].callback.call(context, data);
                idx += 1;
            } 
            else { clearInterval(intervalId); }
        }, 0);
    }

Ответы [ 2 ]

4 голосов
/ 17 февраля 2012

Использование setInterval в данном случае делает выполнение вида «асинхронным», потому что оно планирует выполнение обратного вызова на следующий раз, когда основной поток выполнения доступен.

Это означает, что выполнение обратного вызова не должно блокироватьбраузер, потому что любая другая синхронная обработка будет иметь место перед обратными вызовами (потому что обратные вызовы запланированы для запуска только тогда, когда основной поток выполнения имеет запасную миллисекунду) - и это то, что делает эту конструкцию «лучше», чем обычный цикл for - фактчто обратные вызовы не будут блокировать браузер и вызывать ужасную ошибку «На этой странице слишком длинный скрипт».

Побочным эффектом этого шаблона планирования является то, что тайм-аут является лишь «предложением» -вот почему они используют 0 здесь.

См .: http://ejohn.org/blog/how-javascript-timers-work/

4 голосов
/ 17 февраля 2012

setInterval(..., 0) может использоваться для передачи управления пользовательскому интерфейсу браузера, чтобы предотвратить его зависание, если выполнение кода занимает много времени.

В этом случае that.publish завершится почти сразу, прежде чем будет выполнен любой обратный вызов.После этого каждый обратный вызов будет выполняться «в фоновом режиме» - он будет помещен в цикл обработки событий, и каждый из них будет отдан браузеру для выполнения своей задачи до выполнения следующего обратного вызова.идея в обработке событий, потому что вы не хотите, чтобы обработка событий замораживала браузер, даже если их много или для их завершения требуется много времени.

О документации - как указано, это неправильно,Javascript является однопоточным.Но если бы вам пришлось вызывать publish() несколько раз подряд, это правда, что все эти вызовы завершатся до того, как будут выполнены какие-либо обратные вызовы, из-за setTimeout.Может быть, это то, что означает документация?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...