I am stuck with this in an app development and don't know what to try. I have the following function:
// Function to load Scripts on the fly
$.loadScript = function(url, arg1, arg2) {
var cache = false,
callback = null;
//arg1 and arg2 can be interchangable
if ($.isFunction(arg1)) {
callback = arg1;
cache = arg2 || cache;
} else {
cache = arg1 || cache;
callback = arg2 || callback;
}
var that = this;
var load = true;
var deferred = jQuery.Deferred();
if (jQuery.isFunction(callback)) {
deferred.done(function(){
callback.call(that);
});
};
if( url.constructor === Array ){
function loadScript(i) {
if (i < url.length) {
var el = url[i];
//check all existing script tags in the page for the url
if (window.loadedScripts.indexOf(el) === -1) {
window.loadedScripts.push(el);
//didn't find it in the page, so load it
$.ajax({
url: el,
success: function(e){
__info('Loaded script. url: '+el, 'verbose');
loadScript(i + 1);
},
complete: function(e){
if(typeof e.done !== 'function'){
$(function () {
$('<script>')
.attr('type', 'text/javascript')
.text(e.responseText)
.prop('defer',true)
.appendTo('head');
})
}
},
dataType: 'script',
cache: cache
});
}
//-----------------
} else {
deferred.resolve();
}
}
loadScript(0);
return deferred;
} else {
//check all existing script tags in the page for the url
if (window.loadedScripts.indexOf(url) === -1) {
window.loadedScripts.push(url);
//didn't find it in the page, so load it
$.ajax({
url: url,
success: function(e){
__info('Loaded script. url: '+url, 'verbose');
deferred.resolve();
},
complete: function(e){
if(typeof e.done !== 'function'){
$(function () {
$('<script>')
.attr('type', 'text/javascript')
.text(e.responseText)
.prop('defer',true)
.appendTo('head');
})
}
},
dataType: 'script',
cache: cache
});
} else {
deferred.resolve();
};
}
};
This function works similar to $.getScript, but loads several scripts (or only one), fires a callback at end and introduces cache parameter to deal with custom cache of this app.
It already works fine, except in the case when several scripts are requesting loading in parallel. When this occurs, second set of scripts enter the function, watches that first script (common for the blocks) are loading and don`t load it (but will need to wait for it). But, in this case, in first block the first script is not loaded already and in the second block, this script is needed but is skipped.
Example of use:
<script type="text/javascript">
$.loadScript([
"//code.highcharts.com/highcharts.src.js",
"//code.highcharts.com/modules/data.js",
"//code.highcharts.com/modules/treemap.js"
], true, function(){
$.ajax({
type: 'POST',
url: '/skip-process/charts/graph1',
success: function(data){
console.log($.parseJSON(data));
var chart = new Highcharts.Chart($.parseJSON(data));
}
});
});
</script>
How to deal with several scripts requesting load at the same time the same script and they are not waiting for it? Thanks a lot.
I would approach this using
$.getScriptand using the promise it returns and usingthen()instead of passing a callback into the function.Following is not well tested but should be very close