Использование async не работает $не определено

У меня возникла ошибка, если я использовал async в теге script, как показано ниже

<script async src="main.js"></script>

Ошибка отображается только на хроме, говоря

Uncaught ReferenceError: $ is not defined

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

У вас есть идея, почему у вас есть эта проблема?

ИЗМЕНИТЬ

Ниже script помещаются внутри тега заголовка

<!-- JS -->
<script async src="../js/jquery/jquery-1.10.1.min.js">    </script>
<script async src="../js/vendor/modernizr-2.8.2.min.js"></script>

<script async src="../js/asynchronous-resources/2014-06-03-asynchronous-resources.js"></script>

<!-- IE JS -->
<!--[if !IE]><!--><script async src="../js/ie10.js"></script><!--<![endif]-->

main.js добавляется в нижний колонтитул.

<script async src="../js/main.js"></script>

Я нашел аналогичный вопрос о stackoverflow. Загружать jquery асинхронно перед другими скриптами

Мне пришлось изменить async, чтобы отложить больше, теперь нет проблем в firefox, chrome и IE9.

Byt он полностью разбивается на IE8 и IE7. jQuery перестает работать, если я использую defer.

Ответ 1

Хорошо..... Итак, в основном...

БЕЗ ASYNC:

Файлы JS загружаются и выполняются последовательно В ЗАКАЗ... то есть первый встреченный JS файл загружается и выполняется первым, затем следующим и так далее, в то время как в это время блокировщик HTML блокируется, что означает отсутствие дальнейшего прогресса в HTML-рендеринг.

С ASYNC:

Файлы JS [все] помещаются в асинхронную загрузку по мере их возникновения и выполняются, как только они полностью загружаются. Парсер HTML не блокируется на время их загрузки. Таким образом, рендеринг HTML более прогрессивный.

НЕДОСТАТКИ:

Однако проблема с асинхронной загрузкой и исполнением заключается в том, что файлы JS выполняются, как только они загружаются... т.е. NO ORDER поддерживается... например, меньший JS файл (main.js), который получает загружается до того, как файл большего размера (jQuery.js) выполняется перед большим файлом. Итак, если мой меньший файл ссылается на некоторую переменную/код ($ из jQuery), инициализированную в более крупном файле, увы, код еще не инициализирован, и поэтому возникает ошибка. И вот что здесь происходит.

ЧТО СЛЕДУЕТ СДЕЛАТЬ:

1 > Удалить атрибут async и жить с более низкой производительностью.
2 > Используйте динамическую загрузку скриптов, поддерживающих порядок выполнения. Динамические скрипты загружаются асинхронно по умолчанию, но выполняются отдельно от разбора DOM, поэтому не блокируют рендеринг HTML. В этом случае, написав

script.async = false; 

мы заставляем их загружаться и выполняться в порядке.

<script type="text/javascript">
[
  'jQuery.js',
  'main.js'
].forEach(function(src) {
  var script = document.createElement('script');
  script.src = src;
  script.async = false; 
  document.head.appendChild(script);
});
</script>

Ответ 2

Имел ту же проблему, но хотел сохранить асинхронный режим для лучшей производительности. Я исправил проблему, переместив весь код из main.js в функцию onload. Например:

window.onload = function () {

// main.js code

};

Таким образом, код main.js запускается только после загрузки страницы (включая jQuery).

ОБНОВЛЕНИЕ: Здесь другой способ (лучше?):

var myScript = document.createElement('script');
myScript.src = 'http://code.jquery.com/jquery-1.9.1.min.js';
myScript.onload = function() {
  console.log('jQuery loaded.');
};

document.body.appendChild(myScript);

Ответ 3

Ваш main.js запускается асинхронно даже до того, как jquery будет загружаться синхронно.

Либо добавьте атрибут async в jquery, либо удалите атрибут async из main.js

MDN

Установите этот логический атрибут, чтобы указать, что браузер должен, если возможно, выполните script асинхронно. Это не влияет на встроенные сценарии (то есть скрипты, которые не имеют атрибута src).

Ответ 4

Я только что закончил писать jsinit.js только для этой цели.

Он позволяет использовать async даже с jQuery. Он работает, задерживая выполнение вашего модуля до завершения загрузки jquery. (И он может быть загружен "async" сам по себе!)

Посмотрите: https://github.com/ScheintodX/jqinit.js

Ответ 5

Мое предположение - main.js имеет в нем некоторый jQuery. Асинхронный тег заставит браузер разобрать JavaScript, как только он станет доступен, что может быть до готовности jQuery script.

Из W3schools:

Когда он присутствует, он указывает, что будет выполнен scriptасинхронно, как только он будет доступен.

Чтобы решить:

  • Добавить атрибут async в jQuery в дополнение к main.js
  • Удалить атрибут async из main.js
  • Удалить тэг async вообще

Если вы предоставите дополнительную информацию о том, что используете тег async, я могу предложить еще несколько предложений.

Ответ 6

Этот способ отлично работает на ggle chrome для меня: Заменить

<script async src="JS/jquery-3.1.1.min.js"></script>
<script async src="JS/my.js"></script>

по

<script defer src="JS/jquery-3.1.1.min.js"></script>
<script defer src="JS/my.js"></script>

он заряжает первый jquery и после my.js, как порядок