Я только что узнал важный факт о выполнении javascript в случае возникновения ошибки. Прежде чем я начну делать выводы из этого, я лучше проверю, прав ли я.
Учитывая HTML-страницу, включая 2 скрипта:
<script src="script1.js" />
<script src="script2.js" />
script1:
doSomething();
Скрипт2:
doSomeOtherThing();
Это приводит к тому, что один script обрабатывается как единое целое:
doSomething();
doSomeOtherThing();
В частности, если doSomething
выдает ошибку, выполнение прерывается. "script2" никогда не выполняется.
Это мой "Урок 1" - можно подумать, так как это отдельный файл, на который он не влияет. Но это так. = > см. "последнее обновление" ниже
Теперь, если мы изменим script2 следующим образом (предположим, что мы включили jQuery где-то выше):
$(document).ready({ doSomeOtherThing(); });
и поместите script перед скриптом2:
<script src="script2.js" />
<script src="script1.js" />
Порядок выполнения по-прежнему остается "doSomething()" (иногда) "doSomeOtherThing()".
Однако он выполняется в двух "единицах":
-
doSomething
выполняется в начале документа java script -
doSomeOtherThing
выполняется при обработке события document.ready.
Если doSomeOtherThing
выдает исключение, он будет не разорвать вторую часть обработки.
(Я воздержусь от использования термина thread
, потому что считаю, что все script обычно выполняются одним и тем же потоком, или, точнее, это может зависеть от браузера.)
Итак, моя Lession 2: хотя ошибка JavaScript может помешать выполнению любых последующих скриптов, она не останавливает цикл событий.
Заключение 1
$(document).ready()
отлично справляется с определением фрагментов кода JavaScript, которые должны выполняться независимо от любых других исполняемых скриптов.
Или, другими словами: если у вас есть фрагмент JavaScript и вы хотите убедиться, что он выполняется, даже если другие скрипты не работают, поместите его в $(document).ready()
.
Это было бы ново для меня, потому что я использовал бы только событие, если script зависит от полностью загруженного документа.
Заключение 2
Сделав еще один шаг, было бы хорошим решением архитектуры обернуть все сценарии в $(document).ready()
, чтобы убедиться, что все сценарии "поставлены в очередь" для выполнения. Во втором примере выше, если script2.js
был включен после script1.js
, как в примере 1:
<script src="script1.js" />
<script src="script2.js" />
Ошибка в script1.js помешает doSomeOtherThing()
даже зарегистрироваться, потому что функция $(document).ready()
не будет выполнена.
Однако, если script1.js использовал $(document).ready()
тоже, этого не произошло бы:
$(document).ready(function() { doSomething(); });
$(document).ready(function() { doSomeOtherThing(); });
Обе строки будут выполнены. Затем цикл событий выполнил бы doSomething
, который сломался бы, но doSomeOtherThing
не будет затронут.
Еще одна причина для этого состоит в том, что поток, отображающий страницу, может как можно скорее вернуться, а цикл события может использоваться для запуска выполнения кода.
Критика/Вопросы:
- Я ошибался?
- Какие существуют причины, из-за которых необходимо немедленно выполнить часть кода, т.е. не обернуть ее в событие?
- Будет ли это сильно влиять на производительность?
- Есть ли другой/лучший способ достичь того же, а не использовать событие готовности документа?
- Можно ли определить порядок выполнения скриптов, если все сценарии просто регистрируют свой код как обработчик событий? Выполняются ли обработчики событий в том порядке, в котором они были зарегистрированы?
С нетерпением ждем любых полезных комментариев!
Позднее обновление:
Как правильно указал Briguy37, мое наблюдение, должно быть, было неправильным в первую очередь. ( "Я ошибался - да!" ). Взяв его простой пример, я могу воспроизвести, что во всех основных браузерах и даже в IE8 скрипт2 выполняется, даже если скрипт1 выдает ошибку.
Все еще @Marcello большой ответ помогает получить представление о концепциях стеков исполнения и т.д. Кажется, что каждый из двух сценариев выполняется в отдельном стеке выполнения.