Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using async not working $ is not defined

I am having a error if I used async in script tag like below

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

The error shows only on chrome saying

Uncaught ReferenceError: $ is not defined

If I removed the async from the script tag there is no more error in my console and everything works fine.

Do you have any idea why am having this problem ?

EDIT

Below script are placed inside the head tag

<!-- 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 is added to the footer.

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

I have found a similar question on stackoverflow. Load jquery asynchronously before other scripts

I had to change async to defer there is no more issue now in firefox, chrome and IE9.

Byt it breaks in IE8 and IE7 completely. jQuery stopped working if I use defer.

like image 887
Santosh Avatar asked Jun 15 '14 08:06

Santosh


People also ask

How to await async function in JavaScript?

async and await Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.

How to create async function Nodejs?

The asynchronous function can be written in Node. js using 'async' preceding the function name. The asynchronous function returns implicit Promise as a result. The async function helps to write promise-based code asynchronously via the event-loop.

Can you not await an async function?

In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronously. Code after each await expression can be thought of as existing in a .then callback.

Does async await work in Node JS?

Async functions are available natively in Node and are denoted by the async keyword in their declaration. They always return a promise, even if you don't explicitly write them to do so. Also, the await keyword is only available inside async functions at the moment – it cannot be used in the global scope.


2 Answers

Had the same problem but wanted to keep the async for better performance. I've fixed the problem by moving all code from main.js into an onload function. Like so:

window.onload = function () {

// main.js code

};

This way the main.js code only runs after the page is loaded (including the jQuery).

UPDATE: Here's another (better?) way:

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);
like image 31
nunoarruda Avatar answered Oct 07 '22 20:10

nunoarruda


Okay..... So Basically...

WITHOUT ASYNC:

JS files are downloaded and executed sequentially IN ORDER ... i.e., The first encountered JS file gets downloaded and executed first, then the next and so on, while at this time the HTML parser is blocked which means no further progress in HTML rendering.

WITH ASYNC:

JS files[all] are put to asynchronous download as they are encountered, and are executed as soon as they get fully downloaded. HTML parser is not blocked for the time they are downloaded. So the HTML rendering is more progressive.

DISADVANTAGE:

However, the problem with asynchronous download and execution is that the JS files are executed as soon as they are downloaded... i.e., NO ORDER is maintained..for example, a smaller JS file(main.js) that gets downloaded before a larger file(jQuery.js) gets executed before the larger file. So, if my smaller file has reference to some variable / code ($ of jQuery) initialized in the larger file, alas, the code has not been initialized yet and therefore an error is thrown. And that is what is happening here.

WHAT SHOULD YOU DO:

1> Remove async attribute and live with a lower performance.
2> Use dynamic loading of scripts which maintains the order of execution. Dynamic scripts are downloaded asynchronously by default but are executed seperately from the DOM parsing, therefore not blocking the HTML rendering. In this, by writing

script.async = false; 

we force these to get downloaded and executed IN ORDER.

<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>
like image 156
Vaibhav Avatar answered Oct 07 '22 18:10

Vaibhav