0

Besides jQuery's AJAX functions I'm very limited in my understanding of "asynchronous" JavaScript.

I've created a system where I'm loading external Javascript files in as 'modules' in order to keep things tidy and lightweight. The main inspiration + implementation for doing this can be found here.

So, for example, a JS file called foo.js might contain the following JS object with set attributes:

var bar = { 
   a:1,
   b:2
}

After this external file has been loaded it's accessible via window.bar thereafter. So typing in window.bar.a (alternatively bar.a) into the browser's Developer Tool JS console should return:

1

My issue arises when I try to assign the bar object to a variable, this will often be resolved synchronously before the external JS module has been loaded and usually contain undefined - boo!

This is my attempt so far: basically return the object instance if it already exists in the window, otherwise wait for it to be loaded and then return it (ideally):

var val = getInstance('bar');

Which calls my function:

function getInstance(name) {
    if(typeof window[name] === 'object'){
        return window[name];
    } else { 
        $(window).on('load', window[name], function() { 
            return window[name];
        });
    }
}

Which, of course returns undefined when I console.log(val).

I know for a fact here that I'm expecting the object bar to come through asynchronously to val. To which I can then go ahead and start referencing the bar instance through val (i.e. val.a == 1).

I've made an effort to skim over jQuery's Deferred Object ($.Deferred) - to which my understanding disappears, but I'm on a tight deadline and would like to know now rather than a few days down the line if I'm on the right track in getting and instance of bar into val.

Any help, pointers or comments are much appreciated!

5
  • 1
    "otherwise wait for it to be loaded and then return it (ideally):" can't work asynchronously. I'd suggest using either an existing framework that solves this problem (such as requirejs) or building something similar. Commented Jun 27, 2013 at 14:57
  • 1
    use a callback function Commented Jun 27, 2013 at 14:57
  • @KevinB Hence my question about the whole matter. Getting an instance without having to rely on callbacks is my main objective here - it's simply placeholder code to try and replicate what I'm trying to achieve. Commented Jun 27, 2013 at 15:01
  • 1
    You can't, there must be a callback. Even a setInterval that continuously checks for it to become available requires a callback. Commented Jun 27, 2013 at 15:03
  • zesda, you appear to be describing "jsonp", without using the term "jsonp". Google it and do some reading. Commented Jun 27, 2013 at 15:15

3 Answers 3

1

I think Kevin B has given you the correct answer.

Considering your timeline and unfamiliarity with the topic, I would suggest concatenating and minifying your JavaScript files instead of doing async modules.

Otherwise you will need to invest the time in understanding how to use a module loader like require or yepnope. The article you reference doesn't address loading multiple modules simultaneously, which may be a requirement for you. Any path you take to async script loading is going to require you to leverage callbacks to organize the order that your code is executed.

Sign up to request clarification or add additional context in comments.

Comments

0
var ajaxRequests = [];
var scriptUrlCollection = ['script1.js', 'script2.js', 'script3.js'];
$(scriptUrlCollection).each(function( index, url ) {
    ajaxRequests.push($.getScript(url));
});
$.when.apply($, ajaxRequests).done(function() { / *execute your code */); 

You may use ajax to load your scripts, then execute your code when all of them complete, thanks to deferred objects.

Each ajax request returns a jQuery deferred object, which we add to the ajaxRequests array. When all of these deferred objects are resolved, the done() method is executed.

Comments

0

I would like to know now rather than a few days down the line if I'm on the right track

Yes. Promises (like jQuery's Deferred implementation) are the way to go.

in getting and instance of bar into val

Not exactly. Promises in JS are not transparent, they're more like proxy objects. You still need a callback:

getInstance("bar").then(function(val) {
    // this function is executed asynchronously
    // and the `bar` instance is available here
});

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.