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.
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.
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.
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.
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.
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);
Okay..... So Basically...
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.
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.
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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With