4

how can we make a function from arrays like

$.loader({
    js: [
        ['1.js','3.js','2.js'], 
        ['4.js'], 
        ['5.js'] 
    ]
}); 

into something that does

$.when(
    $.getScript("1.js"),
    $.getScript('3.js'),
    $.getScript('2.js'))
    .then(
        function(){
            $.getScript('4.js').then(function(){
                $.getScript('5.js');
            })
        });

heres what currently im working on

loader: function(arg){
    var js = arg;
    var phase = 0;
    for (var i = 0; i < o.length; i++) {
        console.log(o[i]);
        $.each(o[i], function(key,src) {
            //append javascript
        });
    };
}

enter image description here

the problem is i dont know where to start. heres what i have in mind

  1. i divide them into phases.
  2. set phase 0, it will run the fist array but how can i do it ? $.getScript(src) for each src dosent stack. or chain. maybe put it one var sting ? like string + = $.getScript(src). so it will be like $.getScript("1.js").getScript("3.js").getScript("2.js") until there is arrays of string which is 3 in this example. then do something like append $.when( infront of the string then at the back of the string we put .then(function(){ until it finish then somehow closed the string.
  3. ok i dont know ( and here goes the post at stackoverflow )

3 Answers 3

1
function lScripts(startAt){
for (var i = startAt; i < js.length; i++) {    
    if (js[i].constructor == Array){
        for (var j = 0; j < js[i].length; j++) {
            if(j==js[i].length){
                $.getScript('js[i][j]',function(){
                    lScripts(startAt+1);
                });
            }else{
                $.getScript('js[i][j]');
            }

        }

    }else{
         $.getScript('js[i]',function(){
            lScripts(startAt+1);
         });

    }
}
}

lScripts(0);
Sign up to request clarification or add additional context in comments.

5 Comments

yes im trying to make a function that does slimier like this. from the array that we got. anyway this post shows that it will load 1,3 and if 2 is loaded then to 4, if 4 loaded then to 5. not load 1,3,2 then loads 4 then loads 5. if im correct
i think i understand what you want, try that
do u need it to wait until each index of the js array is completely loaded before moving to the next index? like pause after 2.js and once it loads, then move to the next index?
yes, but its not just 2.js its 1.js,3.js,2.js in array[0] then to array[1] that is 4.js then to array[2] that is 5.js just like in my question example. useing when and then is quite the right thing to do right ?
maybe that? that will load all items in js[0] then once they load it moves to js[1] once that loads it moves to js[2]
1

Just to be clear, are you talking about writing a solution yourself that loads up a bunch of scripts? If so, dont do it yourself. Stand on someone else's shoulders.

RequireJS already does what you're asking. http://requirejs.org/

It even has documentation for use with jQuery. http://requirejs.org/docs/jquery.html

Someone else already did the hard work and wrote and tested a good product. Save yourself time and stress.

Comments

1
+100

I hope this is what you mean: http://jsfiddle.net/pimvdb/hdN3Q/1/.

(function($) {
    function load(files, index) {
        var arr = [];

        // fill arr with getScript requests (fake here)
        for(var i = 0; i < files[index].length; i++) {
            arr.push(console.log(files[index][i]));
        }

        // call $.when with arr as array of arguments (using apply)
        $.when.apply(null, arr).then(function() {
            if(index < files.length - 1) {
                // if we have to move to the next chunk,
                // load that next one
                setTimeout(function() {
                    // timeout is to show they get processed in chunks
                    load(files, index + 1);
                }, 1000);
            }
        });
    }

    $.loader = function(obj) {
        load(obj.js, 0);
    }
})(jQuery);

$.loader({
    js: [
        ['1.js','3.js','2.js'], 
        ['4.js'], 
        ['5.js'] 
    ]
});

.apply essentially does the same thing as calling a function. However, because the amount of arguments to $.when differs depending on the input, you can't just call $.when(...) because you don't have a fixed number of arguments. The way to call a function with a variable amount of arguments is using .apply. It works like this:

someFunction(1, 2, 3);

is equal to:

someFunction.apply(null, [1, 2, 3]);

(The null refers to the execution context which is out of scope here.) The great thing about this is that you can build an array of any size. So you can call the function with any variable amount of arguments this way.

In the load function, arr gets filled with getScript functions, and it works the same way:

var arr = [getScript('file1'), getScript('file2')];
$.when.apply(null, arr);

is equal to:

$.when(getScript('file1'), getScript('file2'));

In load, we fill arr with the files of a chunk, e.g. in your case the first chunk is 1.js, 3.js and 2.js. This is done using a for loop but the array you will end up with you can just pass to .apply.


When all files are loaded, .then is called. The function we pass there should load the next chunk, but only if there is a next chunk. If there are 3 chunks, it should go to the next one when index is 0 or 1. When chunk 2 has finished, there is no next chunk so it should not continue to the next one as there isn't a next one.

So we need this if clause:

if(index < files.length - 1) {

Say files.length is 3. Then this if conditional will only pass when index is 0 or 1, which is what we want.

4 Comments

it work great!. but still im dont quite get how it work especialy $.when.apply(null, arr).then(function() { and if(index < files.length - 1) { please give me some time to read the docs.
btw sometimes $.when.apply(null, arr).then(function() { doesn`t pass i wonder why. adding some bonus. great answer
@Adam Ramadhan: I'm not sure why. Is that the case for getScript? When the script cannot be loaded, .then will not execute because not all requests were successful.
nope its done. again thanks great question and answer. really love this, my fault. you are correct btw.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.