Я только что узнал важный факт о выполнении 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 большой ответ помогает получить представление о концепциях стеков исполнения и т.д. Кажется, что каждый из двух сценариев выполняется в отдельном стеке выполнения.