Пожалуйста, прочитайте следующий код и угадайте результат выполнения:
var start = new Date; setTimeout (function () {console.log ('Time Pass:'+(Новая дата - Start)+'msec');}, 200); while (новая дата - start <1000) {} console.log (1); function dosoming () {settimeout (function () {console.log ('время проходит снова:'+(Новая дата - Start)+'msec');}, 10);} dosoming (); while (новая дата - start <2000) {} console.log (2);оказаться:
Вывод примерно через 1 секунду: 1,
Примерно через 1 секунду выход: 2.
Затем немедленно вывод: время прошло: 2002 миллисекунд
Последний вывод: время прошло снова: 2003 миллисекунд
Вы уже догадались?
Здесь все функции, которые задерживают выполнение путем установки, подталкиваются до конца перед выполнением;
Принцип заключается в следующем:
В существующей среде браузера двигатель выполнения JavaScript однопоточный. Основные операторы и методы основного потока будут блокировать выполнение задач времени. За пределами механизма выполнения JavaScript есть очередь задач. Когда метод settimeout () в коде вызывается, зарегистрированный метод задержки будет подвешен к другим модулям в ядре браузера для обработки. Когда метод задержки достигает условия триггера, то есть время установленного задержки достигает набора, модуль добавит метод для выполнения в очередь задач модуля. Этот процесс не зависит от основного потока механизма выполнения. Двигатель выполнения извлечет задачи из очереди задач модуля последовательно, чтобы выполнить, когда выполняется метод основного потока, и достигнет состояния холостого хода. Время в течение этого периода может быть больше, чем время задержки, установленное при регистрации задачи;
Когда браузер простаивает, он постоянно пытается извлечь задачи из очереди задачи модуля, которая называется моделью цикла событий;
Давайте посмотрим на предыдущий код. Время задержки второго метода задержки SetTimeout () составляет 10 миллисекунд, что запускается раньше, чем первое! Почему результат исполнения позади? Поскольку он был заблокирован предыдущим кодом примерно на 1000,5 ~ 1001 миллисекунд (в зависимости от скорости обработки браузера), когда он висит к модулю обработки и когда время триггера добавляется в очередь задачи, метод задержки первого установки () давно добавляется в команду задачи модуля, а основной нить двигателя получается в порядке, так что вы должны понимать, что?
Теперь, если вы измените приведенное выше (новая дата - Start <1000) {} на while (New Date - Start <189) {} или while (New Date - Start <190) {}, что такое результат? Я не скажу много! Обновите браузер по 20 раз каждый и сами увидите результаты!
Метод setInterval () и setTimeout () имеют одинаковый статус. Когда вызывается метод setInterval (), зарегистрированный метод задержки подвешен к модулю для обработки. Всякий раз, когда наступает время триггера, метод, который нужно выполнять, добавляется в очередь задачи один раз;
Давайте посмотрим на синтаксис SetTimeout:
var timeId = window.settimeout (func, задержка, [param1, param2, ...]);
var timeId = window.settimeout (код, задержка);
SetTimeout и SetInterval - это методы оконных объектов (окно может быть опущено). Вторые дополнительные параметры (не поддерживаемые IE9 и старыми версиями) являются параметрами, передаваемыми в Func. Каждый раз, когда они называются, будет возвращен числовой идентификатор (это всего лишь число, напечатанное в браузере, но я напечатал его в Webstorm и обнаружил, что на самом деле это объект со многими атрибутами). Этот идентификатор сохраняет соответствующую информацию о соответствующей установке или SetInterval, и в основном используется для очистки (или закрытия) их в среднем модуле и очереди задач (используя методы ClearTimeout (ID) и ClearInterval (ID)).
Если вам нужно перенести параметр в функцию обратного вызова, следующее приведено метод совместимых с IE написания
if (document.all &&! window.settimeout.ispolyfill) {var __nativest__ = window.settimeout; window.settimeout = function (vcallback, ndelay, param1, param2, param3) {var aargs = array.prototype.slice.call (аргументы, 2); return __nativest __ (vcallback ancessionof function? function () {vcallback.apply (null, aargs);}: vcallback, ndelay); }; window.settimeout.ispolyfill = true;}Общая ошибка возникает при использовании закрытия в цикле
for (var i = 0; i <10; i ++) {settimeout (function () {console.log (i);}, 1000);}Приведенный выше код выведет номер 10 десять раз. Почему? Закрытие!
Когда называется Console.Log, хотя анонимная функция поддерживает ссылку на внешнюю переменную I, в настоящее время цикл закончился, а значение I изменяется на 10.
Чтобы получить желаемый результат, копию переменной, которую я должен создать в каждом цикле.
Чтобы правильно получить номер цикла, лучше всего использовать анонимную обертку (на самом деле то, что мы обычно называем самостоятельными анонимными функциями).
for (var i = 0; i <10; i ++) {(function (e) {settimeout (function () {console.log (e);}, 1000);}) (i);}Внешняя анонимная функция будет выполнена немедленно, и я буду использоваться в качестве его параметра. В настоящее время переменная E в функции будет иметь копию i.
Когда анонимная функция, передаваемая в Settimeout, выполняется, она имеет ссылку на E, и это значение не будет изменено с помощью цикла.
Есть другой способ выполнить ту же работу; То есть вернуть функцию из анонимной обертки. Это работает так же, как приведенный выше код.
for (var i = 0; i <10; i ++) {settimeout ((function (e) {return function () {console.log (e);}}) (i), 1000)}Другое важное приложение: функция дросселя и функция деберуют
Пожалуйста, посмотрите некоторую информацию, которую я собрал в Интернете:
JavaScript - Функция оптимизации производительности и функция дебайт
Ссылка на ссылку:
https://developer.mozilla.org/zh-cn/docs/web/api/window/settimeout
http://www.alloyteam.com/2015/10/turning-to-javascript-series-from-settimeout-said-the-event-loop-model/#prettyphoto
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.