С тех пор как стало возможным указать загружаемому в HTML документе скрипту флаги-аттрибуты async и defer, стало необходимо понимать то, в какой очередности скрипты будут исполнены, если они зависят друг от друга.
Так если ваш скрипт зависит от jQuery-плагина, а тот в свою очередь от самой библиотеки jQuery, и все они загружаются асинхронно, то гарантировать определенную очередность запуска не возможно.
Необходим механизм запуска одного скрипта, после готовности другого. Я использую следующую snippet-функцию (к сожалению утерял первоисточник откуда взят код), которая реализует данный механизм:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* Async script load with callback */ function loadScript(url, callback) { var script = document.createElement("script"); script.type = "text/javascript"; script.async = true; if (script.readyState) { script.onreadystatechange = function () { if (script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; if (callback && typeof callback === "function") { callback(); } } }; } else { script.onload = function () { if (callback && typeof callback === "function") { callback(); } }; } script.src = url; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script); } |
Данная функция позволяет привязать вашу callback функцию к событию готовности скрипта onload.
Обычно библиотека загружается асинхронно, а код, использующий её, идет inline. В таком случае удобно использовать подсистему events.
1 2 3 4 5 6 7 |
loadScript( 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.6.0/leaflet.js', () => { jQuery(document) .trigger('leafletIsLoaded') .trigger('leafletIsCompletelyReady') } ); |
В примере выше я привязываю последовательный вызов событий leafletIsLoaded и leafletIsCompletelyReady к загрузке библиотеки leaflet.js. Оба события кастомные и могут быть вызваны только принудительно через механизм trigger.
Их я объявляю в произвольном месте как inline код:
1 2 3 4 5 |
<script> $(document).on('leafletIsCompletelyReady', function(e) { ... }); </script> |
Необходимость в цепочки событий может быть обусловлена тем, что вы, к примеру, расширяете функционал (прототип) библиотеки своими методами, а только затем уже можете переходить к использованию библиотеки. Тогда для события leafletIsLoaded вы добавите зацепку вида:
1 2 3 4 5 6 |
<script> $(document).bind('leafletIsLoaded', function(e) { // L - это объект библиотеки leaflet.js $.extend(true, L, { ... }); }); </script> |