views:

169

answers:

5

Hey there!

This is my first post on stackoverflow, so please don't flame me too hard if I come across like a total nitwit or if I'm unable ot make myself perfectly clear. :-)

Here's my problem: I'm trying to write a javascript function that "ties" two functions to another by checking the first one's completion and then executing the second one.

The easy solution to this obviously would be to write a meta function that calls both functions within it's scope. However, if the first function is asynchronous (specifically an AJAX call) and the second function requires the first one's result data, that simply won't work.

My idea for a solution was to give the first function a "flag", i.e. making it create a public property "this.trigger" (initialized as "0", set to "1" upon completion) once it is called; doing that should make it possible for another function to check the flag for its value ([0,1]). If the condition is met ("trigger == 1") the second function should get called.

The following is an abstract example code that I have used for testing:

<script type="text/javascript" >

/**/function cllFnc(tgt) { //!! first function

    this.trigger = 0 ;
    var trigger = this.trigger ;

    var _tgt = document.getElementById(tgt) ; //!! changes the color of the target div to signalize the function's execution
        _tgt.style.background = '#66f' ;

    alert('Calling! ...') ;

    setTimeout(function() { //!! in place of an AJAX call, duration 5000ms

            trigger = 1 ;

    },5000) ;

}

/**/function rcvFnc(tgt) { //!! second function that should get called upon the first function's completion

    var _tgt = document.getElementById(tgt) ; //!! changes color of the target div to signalize the function's execution
        _tgt.style.background = '#f63' ;

    alert('... Someone picked up!') ;

}

/**/function callCheck(obj) {   

            //alert(obj.trigger ) ;      //!! correctly returns initial "0"                         

    if(obj.trigger == 1) {              //!! here's the problem: trigger never receives change from function on success and thus function two never fires 

                        alert('trigger is one') ;
                        return true ;
                    } else if(obj.trigger == 0) {
                        return false ;
                    }


}

/**/function tieExc(fncA,fncB,prms) {

        if(fncA == 'cllFnc') {
            var objA = new cllFnc(prms) ;   
            alert(typeof objA + '\n' + objA.trigger) ;  //!! returns expected values "object" and "0"
        } 

        //room for more case definitions

    var myItv = window.setInterval(function() {

        document.getElementById(prms).innerHTML = new Date() ; //!! displays date in target div to signalize the interval increments


        var myCallCheck = new callCheck(objA) ; 

            if( myCallCheck == true ) { 

                    if(fncB == 'rcvFnc') {
                        var objB = new rcvFnc(prms) ;
                    }

                    //room for more case definitions

                    window.clearInterval(myItv) ;

            } else if( myCallCheck == false ) {
                return ;
            }

    },500) ;

}

</script>

The HTML part for testing:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd >

<html>

<head>

    <script type="text/javascript" >
       <!-- see above -->
    </script>

    <title>

      Test page

    </title>


</head>

<body>

    <!-- !! testing area -->

        <div id='target' style='float:left ; height:6em ; width:8em ; padding:0.1em 0 0 0; font-size:5em ; text-align:center ; font-weight:bold ; color:#eee ; background:#fff;border:0.1em solid #555 ; -webkit-border-radius:0.5em ;' >
            Test Div
        </div>

        <div style="float:left;" >
            <input type="button" value="tie calls" onmousedown="tieExc('cllFnc','rcvFnc','target') ;" />
        </div>

<body>


</html>

I'm pretty sure that this is some issue with javascript scope as I have checked whether the trigger gets set to "1" correctly and it does. Very likely the "checkCall()" function does not receive the updated object but instead only checks its old instance which obviously never flags completion by setting "this.trigger" to "1". If so I don't know how to address that issue.

Anyway, hope someone has an idea or experience with this particular kind of problem.

Thanks for reading!

FK

+5  A: 

You can take advantage of a feature of JS called closure. Combine that with a very common JS pattern called "continuation passing style" and you have your solution. (Neither of these things are original to JS, but are heavily used in JS).

// a function
function foo(some_input_for_foo, callback)
{
    // do some stuff to get results

    callback(results); // call our callback when finished
}

// same again
function bar(some_input_for_bar, callback)
{
    // do some stuff to get results

    callback(results); // call our callback when finished
}

The "continuation passing style" refers to the callback. Instead of returning a value, each function calls a callback (the continuation) and gives it the results.

You can then tie the two together easily:

foo(input1, function(results1) {

    bar(results1, function(results2) {

        alert(results2);
    });
});

The nested anonymous functions can "see" variables from the scope they live in. So there's no need to use special properties to pass information around.

Update

To clarify, in your question's code snippet, it's clear that you are thinking roughly like this:

I have a long-running asynchronous operation, so I need to know when it finishes in order to start the next operation. So I need to make that state visible as a property. Then elsewhere I can run in a loop, repeatedly examining that property to see when it changes to the "completed" state, so I know when to continue.

(And then as a complicating factor, the loop has to use setInterval to start running and clearInterval to quit, to allow other JS code to run - but it's basically a "polling loop" nevertheless).

You do not need to do that!

Instead of making your first function set a property on completion, make it call a function.

To make this absolutely clear, let's refactor your original code:

function cllFnc(tgt) { //!! first function

    this.trigger = 0 ;
    var trigger = this.trigger ;

    var _tgt = document.getElementById(tgt) ; //!! changes the color...
    _tgt.style.background = '#66f' ;

    alert('Calling! ...') ;

    setTimeout(function() { //!! in place of an AJAX call, duration 5000ms

        trigger = 1 ;

    },5000) ;
}

[Update 2: By the way, there's a bug there. You copy the current value of the trigger property into a new local variable called trigger. Then at the end you assign 1 to that local variable. No one else is going to be able to see that. Local variables are private to a function. But you don't need to do any of this anyway, so keep reading...]

All we have to do is tell that function what to call when it's done, and get rid of the property-setting:

function cllFnc(tgt, finishedFunction) { //!! first function

    var _tgt = document.getElementById(tgt) ; //!! changes the color...
    _tgt.style.background = '#66f' ;

    alert('Calling! ...') ;

    setTimeout(function() { //!! in place of an AJAX call, duration 5000ms

        finishedFunction(); // <-------- call function instead of set property

    },5000) ;
}

There's now no need for your "call-check" or your special tieExc helper. You can easily tie two functions together with very little code.

var mySpan = "#myspan";

cllFnc(mySpan, function() { rcvFnc(mySpan); });

Another advantage of this is that we can pass different parameters to the second function. With your approach, the same parameters are passed to both.

For example, the first function might do a couple of calls to an AJAX service (using jQuery for brevity):

function getCustomerBillAmount(name, callback) {

    $.get("/ajax/getCustomerIdByName/" + name, function(id) {

        $.get("/ajax/getCustomerBillAmountById/" + id), callback);

    });
}

Here, callback accepts the customer bill amount, and the AJAX get call passes the received value to the function we pass it, so the callback is already compatible and so can directly act as the callback for the second AJAX call. So this is itself an example of tying two asynchronous calls together in sequence and wrapping them in what appears (from the outside) to be a single asynchronous function.

Then we can chain this with another operation:

function displayBillAmount(amount) {

    $("#billAmount").text(amount); 
}

getCustomerBillAmount("Simpson, Homer J.", displayBillAmount);

Or we could (again) have used an anonymous function:

getCustomerBillAmount("Simpson, Homer J.", function(amount) {

    $("#billAmount").text(amount); 
});

So by chaining function calls like this, each step can pass information forward to the next step as soon as it is available.

By making functions execute a callback when they're done, you are freed from any limitations to how each functions works internally. It can do AJAX calls, timers, whatever. As long as the "continuation" callback is passed forward, there can be any number of layers of asynchronous work.

Basically, in an asynchronous system, if you ever find yourself writing a loop to check a variable and find out if it has changed state, then something has gone wrong somewhere. Instead there should be a way to supply a function that will be called when the state changes.

Update 3

I see elsewhere in comments you mention that the actual problem is caching results, so all my work explaining this was a waste of time. This is the kind of thing you should put in the question.

Okay, here's how you do caching. Suppose you have a complex way of getting a person's tax records from a database. Internally it uses AJAX - we don't care, because it's been written correctly to accept a callback:

function lookupTaxRecords("Homer J. Simpson", function(taxes) { alert(taxes); });

But you want to use that information elsewhere without repeatedly making the same expensive call. So do this:

var cachedTaxRecords = {};

function lookupTaxRecordsWithCache(name, callback) {

    var taxes = cachedTaxRecords[name];
    if (taxes) {
        callback(taxes); // already got it
    } else {

        lookupTaxRecords(name, function(received) {

            cachedTaxRecords[name] = received; // store for next time
            callback(received);
        });
    }
}

Now when you call this wrapper version, it keeps previous results for later use. It is made possible by using callbacks consistently everywhere.

Another way to share results is to provide a way for one callback to "broadcast" or "publish" to several subscribers:

function pubsub() {
    var subscribers = [];

    return {
        subscribe: function(s) {
            subscribers.push(s);
        },
        publish: function(arg1, arg2, arg3, arg4) {
            for (var n = 0; n < subscribers.length; n++) {
                subscribers[n](arg1, arg2, arg3, arg4);
            }
        }
    };
}

So:

finished = pubsub();

// subscribe as many times as you want:

finished.subscribe(function(msg) {
    alert(msg);
});

finished.subscribe(function(msg) {
    window.title = msg;
});

finished.subscribe(function(msg) {
    sendMail("[email protected]", "finished", msg);
});

Then let some slow operation publish its results:

lookupTaxRecords("Homer J. Simpson", finished.publish);

When that one call finishes, it will now call all three subscribers.

Daniel Earwicker
It would be nice if we had better support for this. Code with umpteen function calls with callbacks, nested knee deep, isn't easy to follow or to write.
reinierpost
@reinierpost - There's a non-standard JS feature in Mozilla that really helps: http://smellegantcode.wordpress.com/2010/02/08/javascript-generators/ - sadly not much use unless it get standardised across browsers, which is unlikely for a long while.
Daniel Earwicker
Hi, thanks for your answer! If I tie functions together like that, I will be (I believe) unable to seperate a function call that uses the data and the function that makes the data. In that case I could just make another AJAX call and leave all dependant functions to a callback chain. That's however not what I want to do: I'd like to have a function that check's whether the data are ready "from the outside".
FK82
@ Daniel Earwicker: the link you posted seems interesting, I will check it out. Thanks.
FK82
@FK82 - I'll try adding more details but feel free to leave more comments if it's still not clear.
Daniel Earwicker
@ Daniel Earwicker: ty
FK82
@ Daniel Earwicker: I do appreciate your effort. Thanks for that. My problem however is not one of caching. Thus I did not put it in the question. Again, I want to check whether the callback function has returned it's results "from outside" the callback-chain. If that is possible I won't have to chain my processing function to the data-fetching function as you suggest. Keep in mind that I know how to do callback chains. This is more of an experimental thing aiming at code simplification.
FK82
@ Daniel Earwicker: btw, your pointer to the reference bug using "var trigger = this.trigger" instead of "var that = this; that.trigger" is a definite help as my checking function now correctly identifies the property change! Tyvm.
FK82
I think you're doing code complication, not code simplification. Note how I was able to delete half the code from your question and achieve the same thing (and it was easy to do it without any bugs, due to less code). Chaining function calls is the *easy* and *natural* way to do this in JS. It lets you create operations that are building blocks that plug together easily. You don't have to permanently tie your the processing function to the data-fetching function. You can plug them together when you need to, *extremely easily*, but they are still perfectly separate software components.
Daniel Earwicker
This is automatically possible in JS as long as each async function takes a function as its last parameter, which it calls onto when the operation completes, passing the results. That is *definitely* the *correct* way to write a reusable asynchronous software component in JS that gives callers total flexibility in how they use it in combination with other components and in one-off situations.
Daniel Earwicker
And if all you take away from this is that one bug fix, but you still think polling for a change in state is a good idea, then I've failed to explain *anything* of much use to you. What's really ironic is that you're using an async callback to check for the state change!
Daniel Earwicker
@ Daniel Earwicker: I have to disagree, using the completion check linearizes (if you can say that), otherwise needlessly wrapped code. This is simplification afaic. Anyway, you will have to wait until I post my final code, but I'm pretty sure you will see that yours and mine are different approaches to the same problem.
FK82
@FK82 - I look forward to seeing it...
Daniel Earwicker
@ Daniel Earwicker: If that wasn't to be ironic, the final code is below. I already posted it a week ago. Btw, in my real code I have now integrated callback chains. I don't like them, but that does not mean that they aren't useful. So, thanks for you help, indeed. If however there was a use where callback chains aren't the best solution (such as if you don't know the function to be called yet and need to wait for user input), there is probably no other way than polling, even if it seems like a crude style of coding to yourself.
FK82
@FK82 - I didn't see the new answer from you (I looked for an update to the original question), so it wasn't ironic. But to reiterate - obviously they are different approaches to the same problem. But one of them is unnecessary, counterproductive, wasteful, unreliable, slow, etc., compared to the simple, fast, effective alternative, and this is true under all circumstances, without any exception. So it's like saying there are two ways to walk to my house, one by following the street signs directly, and the other by taking a detour via the Andes, the Rocky Mountains and Australia...
Daniel Earwicker
You suggest a polling scenario: "such as if you don't know the function to be called yet and need to wait for user input" Okay, think about how that is already solved in the browser. It calls you, e.g. via `onclick` or `onkeydown` or `onchange`. So that is also done with a callback. It's a solved problem. The existing solution is elegant, simple, reusable and has none of the imaginary problems you attribute to it. You need to grasp the power of functions-as-values in JavaScript. They can be passed as parameters. This allows *perfect* separation of responsibilities.
Daniel Earwicker
Polling with a timer doesn't provide *any* additional advantage in terms of modular separation. Separate modular pieces of code do not need to know about each other at all. They accept *parameters* that tell them what to call when they are done; the next step is not hard-coded at all. *It is a parameter*. It's left entirely open.
Daniel Earwicker
Look, I already implemented all valid suggestions (including yours). My question however wasn't on how to write callback chains but on how to adress a state change in a call **without a callback** (e.g. with a poll). This was experimental as I only wanted to know how to do it. Never was I saying that one **should** do a poll. That being said, there really is no point of reprimanding my solution either. In fact it seems very pointless.
FK82
@FK82 - but your solution *does* use a callback. Look closely! And I'm giving up my free time to give you free information - if you don't want it, then yes, this is pointless.
Daniel Earwicker
Yes. It does use a callback for setting the status of the callee to completion. It does **not** use a callback for the function that handles the usage of the data, and thus untangles both. There's a difference to the scenario that you have in mind. I apologize if I failed to make that clear. --- And again, I do appreciate your input (as I do anyone else's).
FK82
@FK82 - I'm talking about the second callback usage: you pass one to `window.setInterval` as well. So you do use a callback on the receiving side as well. You *have* to, because otherwise you will hang up the browser. I've exhausted all my ways of explaining this, but you have "untangled" nothing at all here. You've just added an unnecessary amount of additional CPU work to the browser. You've turned what could be a simple `finished(result)` into a lot of complexity that has *precisely* the same effect (assuming it works correctly) as that simple `finished(result)` call.
Daniel Earwicker
That's nitpicking. The callback that would in a chain of callbacks need to be inside the first function (the initial call) is **not** in fact inside the call (by means of reference), but outside of it, as the function that checks for the completion does not need to be called within the first function but at whatever stage (on whatever trigger) you please. That's the difference. You might well not understand the purpose of it, but that's the matter of the fact.
FK82
I definitely don't understand the purpose of it, that's correct. It achieves exactly the same purpose as a simple callback, but with the addition of a lot of code and extra looping done inside the browser. *Whatever* this is intended to achieve can be far more easily achieved without looping in a timer and checking a property value.
Daniel Earwicker
Fair enough. Thanks for your continued input.
FK82
+4  A: 

Hi and welcome to SO!

The definitive answer to this "call me when you're ready" problem is a callback. A callback is basically a function that you assign to an object property (like "onload"). When object state changes, the function is called. For example, this function makes an ajax request to the given url and screams when it's complete:

function ajax(url) {
    var req = new XMLHttpRequest();  
    req.open('GET', url, true);  
    req.onreadystatechange = function (aEvt) {  
        if(req.readyState == 4)
            alert("Ready!")
    }
    req.send(null);  
}

Of course, this is not flexible enough, because we presumably want different actions for different ajax calls. Fortunately, javascript is a functional language, so we can simply pass the required action as a parameter:

function ajax(url, action) {
    var req = new XMLHttpRequest();  
    req.open('GET', url, true);  
    req.onreadystatechange = function (aEvt) {  
        if(req.readyState == 4)
            action(req.responseText);
    }
    req.send(null);  
}

This second function can be used like this:

 ajax("http://...", function(text) {
      do something with ajax response  
 });

As per comments, here an example how to use ajax within an object

function someObj() 
{
    this.someVar = 1234;

    this.ajaxCall = function(url) {
        var req = new XMLHttpRequest();  
        req.open('GET', url, true);  

        var me = this; // <-- "close" this

        req.onreadystatechange = function () {  
            if(req.readyState == 4) {
                // save data...
                me.data = req.responseText;     
                // ...and/or process it right away
                me.process(req.responseText);   

            }
        }
        req.send(null);  
    }

    this.process = function(data) {
        alert(this.someVar); // we didn't lost the context
        alert(data);         // and we've got data!
    }
}


o = new someObj;
o.ajaxCall("http://....");

The idea is to "close" (aliased) "this" in the event handler, so that it can be passed further.

stereofrog
Hi and thanks for your reply!I (think I) know my way around AJAX and I already use callback functions to handle the response. The problem is another one: basically what I want to do is to make the AJAX callback save the data to the instance of the function it's a member of (i.e. the function that fetches the xml data via XHR).That way the data are ready for every other function that wants to use them and I only have to make one AJAX call for the same set of data instead of multiple (which comes in handy if the file is large or the connection is slow).
FK82
In that case obviously if the data are in fact not ready any function will result in an error. And that's exactly what I want to find a solution for.
FK82
hmm i'm not sure i'm getting it. Maybe you could post some pseudocode... most probably what you need is a closure
stereofrog
@FK82, not sure entirely if I'm getting you, but are you thinking of caching the server's response, so future requests can be served from the cache instead of an actual HTTP call?
Anurag
@stereofrog: Basically it looks like this, I have a class, function metaFunction() { this.AjaxCall = function(url,args) { this.trigger = 0 ; var trigger = 1 ; this.data ; var data = this. data var rqs = new XMLHttpRequest() ; ... rqs.onreadystatechange = function() { ... data = rqst.responseText ; trigger = 1 ; ... } ; rqs.send(null) ; ... } ; this.IWantData = function(obj) { //use Data } ; }
FK82
/* Sorry for the code mess above, there's apparently no line feeds in comments */Anyway I now have an instance of metaFunction (var myMeta = new metaFunction() ) in the current window and I want to have the result of the AjaxCall saved to it (metaFunction.data = new metaFunction.AjaxCall(...).data, so that I may use it for any other member method of metaFunction (e.g. a JSON builder) that requires them. The problem is that I need to somehow check whether AjaxCall.data is actually there before running any additional code.
FK82
@ Anurag: Afaik AJAX calls -- at least in Webkit -- automatically get cached unless you disable the option in the settings. Most browsers do that I believe. I don't have any direct access to the AJAX calls response data however unless I do another call, right? That again will unnecessarily use up resources.
FK82
@FK82 answer updated, look if this helps
stereofrog
Thanks again. What you suggest makes sense for a chain of executions. What I intend to do is to unchain those two methods, so that I have the option of calling someObject.process() -- without doing the AJAX call all over -- particularly upon DOMEvent. In order to do this, someObject.process() must be able to check whether someObject.ajaxCall() has returned data yet, without being in the callback. Unless process() won't find "data" as part of it's arguments, since it is in fact undefined. It's kind of tricky.
FK82
calling `process` from within the callback is not a must, you can simply save data: `me.data=responseText` and in `process` check if it's present: `if(this.data)...else...`
stereofrog
Which will return an error if this.data is actually not ready since the AJAX call is asynchronous and any code running outside of it will execute at the same time.
FK82
A: 

A very simple solution would be to make your first ajax call synchronous. It's one of the optional parameters.

James Westgate
Though not a very good idea in a browser.
Daniel Earwicker
@ James Westgate: first thing I tried, it worked in Webkit (Safari) but not in Moz and Opera (haven't tried IE yet).
FK82
+1  A: 

Welcome to SO! Btw, You come across as a total nitwit and your question is totally unclear :)

This is building upon @Daniel's answer of using continuations. It is a simple function that chains multiple methods together. Much like how the pipe | works in unix. It takes a set of functions as its arguments which are to be executed sequentially. The return value of each function call is passed on to the next function as a parameter.

function Chain() {
    var functions = arguments;

    return function(seed) {
        var result = seed;

        for(var i = 0; i < functions.length; i++) {
            result = functions[i](result);
        }

        return result;
    }
}

To use it, create an object from Chained passing all functions as parameters. An example you can test on fiddle would be:

​var chained = new Chain(
    function(a) { return a + " wo"; },
    function(a) { return a + "r"; },
    function(a) { return a + "ld!"; }
);

alert(chained('hello')); // hello world!

​To use it with an AJAX request, pass the chained function as the success callback to the XMLHttpRequest.

​var callback = new Chain(
    function(response) { /* do something with ajax response */ },
    function(data) { /* do something with filtered ajax data */ }
);

var req = new XMLHttpRequest();  
req.open('GET', url, true);  
req.onreadystatechange = function (aEvt) {  
    if(req.readyState == 4)
        callback(req.responseText);
}
req.send(null);  

The important thing is that each function depends on the output of the previous function, so you must return some value at each stage.


This is just a suggestion - giving the responsibility of checking whether data is available locally or an HTTP request must be made is going to increase the complexity of the system. Instead, you could have an opaque request manager, much like the metaFunction you have, and let it decide if the data is to be served locally or remotely.

Here is a sample Request object that handles this situation without any other objects or functions knowing where the data was served from:

var Request = {
    cache: {},

    get: function(url, callback) {
        // serve from cache, if available
        if(this.cache[url]) {
            console.log('Cache');
            callback(this.cache[url]);
            return;
        }
        // make http request
        var request = new XMLHttpRequest();
        request.open('GET', url, true);
        var self = this;
        request.onreadystatechange = function(event) {
            if(request.readyState == 4) {
                self.cache[url] = request.responseText;
                console.log('HTTP');
                callback(request.responseText);
            }
        };
        request.send(null);
    }
};

To use it, you would make a call to Request.get(..), and it returns cached data if available or makes an AJAX call otherwise. A third parameter could be passed to control how long the data should be cached for, if you're looking for granular control over caching.

Request.get('<url>', function(response) { .. }); // HTTP
// assuming the first call has returned by now
Request.get('<url>', function(response) { .. }); // Cache
Request.get('<url>', function(response) { .. }); // Cache
Anurag
Thanks. This is really cool code for a chained execution. Passing functions using the arguments property is a really nice idea. Yet, what I want really is to check for the data from without a function chain (e.g. depending on user input). Don't get me wrong a chain is a good idea and probably best practice, but it's not a good option if your xml is larger, since the browser will take up a lot of resources to process that each call. Because of that I only want one call whose result gets saved to some child object of the window (e.g. the meta function I talked about above).
FK82
I agree, chaining might be a solution to some problem, but not for this one. I have updated my answer to include caching of responses to avoid overhead.
Anurag
+1  A: 

Hey guys,

I've worked it out and it seems to work perfectly well now. I will post my code later after I have sorted it out. In the meantime, thanks a lot for you assistance!

Update

Tried the code in Webkit (Safari, Chrome), Mozilla and Opera. Seems to work just fine. Looking forward to any replies.

Update 2

I changed the tieExc() method to integrate Anurag's chained function call syntax. Now you can call as many functions as you want upon completion check by passing them as arguments.

If you are not inclined to read the code, try it: http://jsfiddle.net/UMuj3/ (btw, JSFiddle is a really neat site!).

JS-Code:

/**/function meta() {

var myMeta = this ;

/**  **/this.cllFnc = function(tgt,lgt) { //!! first function

    this.trigger = 0 ;  //!! status flag, initially zero
    var that = this ;   //!! required to access parent scope from inside nested function

    var _tgt = document.getElementById(tgt) ; //!! changes the color of the target div to signalize the function's execution
    _tgt.style.background = '#66f' ;

    alert('Calling! ...') ;

    setTimeout(function() { //!! simulates longer AJAX call, duration 5000ms

        that.trigger = 1 ;  //!! status flag, one upon completion

    },5000) ;

} ;

/**  **/this.rcvFnc = function(tgt) { //!! second function that should get called upon the first function's completion

    var _tgt = document.getElementById(tgt) ; //!! changes color of the target div to signalize the function's execution
    _tgt.style.background = '#f63' ;

    alert('... Someone picked up!') ;

} ;

/**  **/this.callCheck = function(obj) {    

    return (obj.trigger == 1)   ?   true
        :   false
        ;

} ;

/**  **/this.tieExc = function() {

    var functions = arguments ;

    var myItv = window.setInterval(function() {

        document.getElementById('target').innerHTML = new Date() ; //!! displays date in target div to signalize the interval increments

        var myCallCheck = myMeta.callCheck(functions[0]) ; //!! checks property "trigger"

        if(myCallCheck == true) { 

            clearInterval(myItv) ;

            for(var n=1; n < functions.length; n++) {

                functions[n].call() ;

            }

        } else if(myCallCheck == false) { 
            return ;
        }

    },100) ;



} ;

}​

HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd >

<html>

<head>

    <script type='text/javascript'  >
        <!-- see above -->
    </script>
    <title>

      Javascript Phased Execution Test Page

    </title>

</head>

<body>

        <div id='target' style='float:left ; height:7.5em ; width:10em ; padding:0.5em 0 0 0; font-size:4em ; text-align:center ; font-weight:bold ; color:#eee ; background:#fff;border:0.1em solid #555 ; -webkit-border-radius:0.5em ;' >
            Test Div
        </div>

        <div style="float:left;" >
            <input type="button" value="tieCalls()" onmousedown="var myMeta = new meta() ; var myCll = new myMeta.cllFnc('target') ; new myMeta.tieExc(myCll, function() { myMeta.rcvFnc('target') ; }, function() { alert('this is fun stuff!') ; } ) ;" /><br />
        </div>

<body>


</html>
FK82
You should look into using jQuery - I'd be surprised if that runs in every browser correctly.!
James Westgate
If there's an issue with one of the major browsers I'd like to know. You don't seem to point one out however.
FK82
An off-topic suggestion: Take a look at the `bind` function from the Prototype library: http://www.prototypejs.org/api/function/bind - it'll give you a nice way to avoid the `var that = this;` workaround. And even better, it will be part of JavaScript itself when ECMAScript 5 is implemented, so it's totally future-proofed.
Jimmy Cuadra