Как избежать потерянных звонков на внешний JS-файл перед его загрузкой - PullRequest
2 голосов
/ 08 января 2011

Моя проблема в том, что несколько веб-сайтов будут включать мой файл JS, и при вызове что-то вроде этого:

<script src="..."></script>

hello.say("yay");

возникнет проблема расы, так что иногда это может случиться, а иногда нет. я знаю, что могу легко решить эту проблему, поместив каждую функцию в window.onload, но это было бы непросто, поскольку я видел, как другие веб-сайты волшебным образом решают эту проблему, например, в Google Analytics:

.. Calling google analytics JS..

<script type="text/javascript">
try{
var pageTracker = _gat._getTracker("UA-xxxxxx-x");     <-- this an object !
pageTracker._trackPageview();
} catch(err) {}
</script>

Как это сделать?

Ответы [ 4 ]

4 голосов
/ 08 января 2011

Google Analytics использует трюк, который является прекрасным примером того, что может быть сделано только на типизированных языках.Основным объектом является массив, если GA-скрипт не загружен, но если он есть, он меняет поведение.Давайте посмотрим, смогу ли я это объяснить.

Я вытащил этот фрагмент из источника здесь в stackoverflow:

var _gaq = _gaq || [];
_gaq.push(['_setAccount','UA-5620270-1']);
_gaq.push(['_trackPageview']);

Это похоже на массив с некоторыми значениями, помещаемыми в него.Фактически, если _gaq равно falsy , когда этот код запускается (как это происходит, если никакой другой аналитический JavaScript-код еще не запущен), он представляет собой массив.Затем, когда основной сценарий аналитики (включенный в тег script в любом месте на странице) загружается, он проверяет этот массив и выполняет некоторую задачу на основе содержимого массива.

Итак, если это происходит в обратном порядке(основной сценарий загружается первым, а затем фрагмент выше) основной сценарий устанавливает _gaq для объекта с помощью push-метода, который делает то, что хочет от Google.Позже, когда приведенный выше код запускается, _gaq.push не просто добавляет значения в массив;фактически он выполняет произвольный код (и вообще не передает его в массив).

Следовательно, независимо от того, какой скрипт запускается первым, конечный результат будет одинаковым, когда оба будут завершены.

0 голосов
/ 09 января 2011

Я немного неуверен в том, что вы думаете о проблеме расы здесь.

Браузеры всегда * выполняют теги скрипта в том порядке, в котором они их видят. Если бы это не было правдой, сломалась бы большая часть Интернета, равно как и почти любая распространенная библиотека JavaScript.

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

Если пользователи могут загрузить ваш скрипт ПОСЛЕ того момента, когда они используют его API, то уловка, на которую ссылается Якоб в своем ответе, сработает. Но я даже не уверен, что вы стремитесь к этому уровню сложности.

* edit: Я должен отметить, чтобы быть совершенно честным, есть определенные исключения из этого, но не настолько, если вы просто имеете дело со стандартным безоткладным использованием тегов <script> в документе HTML.

0 голосов
/ 08 января 2011

Вам нужно будет отложить выполнение любого кода JavaScript, который зависит от внешнего JavaScript, до тех пор, пока страница не будет полностью загружена, и вы можете сделать это, прикрепив выполнение к событию window.onload.

window.onload = function() {
  hello.say('yay');
}

Но этот недостаток заключается в том, что он работает только для одной функции и переопределяет все функции, которые изначально были присоединены к этому событию.Вы хотели бы прочитать пост Саймона Уилсона и комментарии для решений о том, как справиться с этой ситуацией.

http://simonwillison.net/2004/May/26/addLoadEvent/

0 голосов
/ 08 января 2011

Если вы включите свой файл в заголовочную часть html-страницы, он будет загружен до запуска любого другого javascript-кода на странице.

UPD: Кроме того, я думаю, что даже файлы, включенные в текст thml, загружаются перед обработкой остальной части javascripts. Вы уверены, что это ваша проблема в первую очередь?

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