Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute javascript when another function exists

I'm writing two scripts in an web environment where I don't have control over the order in which they are loaded. Let's say the two scripts are called MyUtil and DoSomething.

MyUtil contains utilities that I will bind to the window object using window.myUtil = myUtil. I'm then going to call methods of myUtil from within DoSomething.

If MyUtil is loaded first, everything will work. If it's loaded second, window.myUtil will be undefined.

How can I modify the code in DoSomething (and/or MyUtil) to wait until window.myUtil exists before DoSomething executes its code?

NB: I'm using jQuery 1.2.3.

like image 675
Ben McCormack Avatar asked Jun 02 '11 01:06

Ben McCormack


1 Answers

jQuery.Deferred objects provide a very elegant way to do this (I know you're not using jQuery 1.5: I'm just giving you a reason to upgrade ;-):

Assuming we have two scripts co-operating like the following:

// defines utilities    
var util = util || { loaded: $.Deferred() };
(function(){
    $.extend(util, {
        msg: "Hello!"
    });
    util.loaded.resolve();
})();

... and:

// uses them
var util = util || { loaded: $.Deferred() };
util.loaded.then(function(){
    alert(util.msg);
});

... the alert will always fire after the first script has had a chance to define it's utilities no matter the order they load in. This has advantages over the setTimeout and event based approaches in that it's easier to have multiple dependencies (using $.when), doesn't use polling, and you don't have to worry about handling the order-of-loading explicitly.

The only thing that's kind of gross is that all of the modules have to include:

var util = util || { loaded: $.Deferred() };

... and $.extend() it to make sure that they use the same deferred.

like image 126
Aaron Maenpaa Avatar answered Oct 30 '22 18:10

Aaron Maenpaa