abiku
abiku

Reputation: 2246

Loading external scripts async in JavaScript

This is my first module i'm writing in JS and I want to make sure i'm doing it right. It is going to be a simple gallery module but I want it to be able to display youtube and vimeo movies also. In my module I have function called init(). Before i'm displaying the gallery first I want to add all necessary libs, like youtube iframe api and vimeo js api. only after they are loaded I want to display the gallery. so my module looks something like this:

myModule = {};
myModule.isYoutubeApiLoaded = false;
myModule.isVimeoApiLoaded = false;
myModule.controller;
myModule.init = function (){
   myModule.loadYoutubeapi();
   myModule.loadVimeoApi();
   myModule.startController();
}

now startController function looks like this:

myModule.startController  = function (){
   myModule.controller = setInterval(function(
       if (myModule.isYoutubeApiLoaded && myModule.isVimeoApiLoaded ) {
             myModule.buildGallery();
             clearInterval(myModule.controller);
        }
   ), 5);
}

in loadYoutubeapi() and loadVimeoApi() i'm setting the given flags when scripts are loaded. is it a good approach?

Upvotes: 1

Views: 167

Answers (2)

Andrej
Andrej

Reputation: 1736

No, it's not a good approach. It will load CPU and will possibly have unnecessary delay of 5 milliseconds.

Better way would be to add callbacks to loadYoutubeapi() and loadVimeoApi(). Once they finish they must call your new function (e.g. moduleHasLoaded()), which will count loaded modules. When all will be loaded you can call startController().

It will save CPU and will not have a unnecessary delay at all.

Something like this:

myModule = {};
myModule.isYoutubeApiLoaded = false;
myModule.isVimeoApiLoaded = false;
myModule.loaded = false;
myModule.controller;

myModule.loadYoutubeapi = function() {

    /* Do your stuff. */

    myModule.isYoutubeApiLoaded = true;

    myModule.moduleHasLoaded();
}

myModule.loadVimeoApi = function() {

    /* Do your stuff. */

    myModule.isVimeoApiLoaded = true;

    myModule.moduleHasLoaded();
}

myModule.moduleHasLoaded = function() {

    if (!loaded && myModule.isYoutubeApiLoaded && myModule.isVimeoApiLoaded ) {
        loaded = true;
        myModule.buildGallery();
    }

}

myModule.init = function (){
    myModule.loadYoutubeapi();
    myModule.loadVimeoApi();
}

Upvotes: 2

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40298

The simple solution is to use a script loader like lazyload. It allows you to specify the scripts you want to load and run a callback when the are actually loaded, i.e.:

LazyLoad.js([
        "http://www.youtube.com/apiplayer?enablejsapi=1&version=3",
        "...vimeo script...",
        "...other scripts..."
    ],
    function() {
        myModule.buildGallery();
    }
);

The function will be called when all scripts are loaded. The caveat is that you get no error callback, i.e. if a script fails to load. There are also other script loaders besides lazyload.

More complicated solution, but better if you are working on a medium to large size client-side application: Refactor your modules to use require.js.

Upvotes: 1

Related Questions