I've put together a simple jQuery method that puts functions 'on hold'
so that they are called at the right time and with the right
arguments. I thought that some of you may find it useful so here it
is.

In my case, I used this in creating editable areas with FCK text
editor. Instead of using timers and a bunch of functions to check if
the textarea exists yet, and if fck's javascript has loaded, and if
the editor is ready, I used this.

For lack of a better name, I called this function 'waitFor'. I haven't
tested it thoroughly, so if you find a bug (or have any suggestions/
contributions) please post them here.

For example:
$.waitFor(function(){
                var n = this;
                setTimeout(function(){
                        n.next();
                },2000);
                return ['a'];
        },function(a){
                var n = this;
                setTimeout(function(){
                        n.next(a,'b');
                },3000);
        },function(a,b){
                alert(a+' & '+b);
        });

You have three functions that share data, but you want to call each
function only when the previous has finished doing some processing
(e.g. ajax request). I've used a timeout here to signify the
processing part.

The example flows as follows:
1) the first function is called, and 'a' is returned instantly
2) the returned value (a) is saved to be passed on to the following
function
3) after 2 seconds, the second function is called (with 'a' passed as
argument)
4) the second function waits for 3 seconds, and then calls the third
function passing as arguments the letters 'a' and 'b' ('a' was passed
on from the first function)
5) the third function displays the arguments passed from the second
function

Notes:
- inside each function, 'this' refers to the prototype property of the
current function;
- three  methods are added to the prototype of each function:
  1) .next([arguments]) : calls the next function
  2) .tryAgain([delayl]) : calls the current function again, after a
delay (default:10ms)
  3) .return : stores the return value of the current function
- $.waitFor returns a function, so use $.waitFor([functions])() to
immediately start executing functions

The script:

$.extend($, {
       waitFor : function(){
                var funcs = arguments;
                return function(){
                        callNext = function(i,data){
                                var f = funcs[i];
                                var p = f.prototype;
                                p.next = function(){
                                        var d =  (arguments.length>0)
                                                                ? arguments
                                                                : p.return;
                                        callNext((i+1),d);
                                };
                                p.tryAgain = function(interval){
                                        setTimeout(function(){ return 
f.apply(p,data); },(interval ||
10));
                                };
                                p.return = f.apply(p,data);
                        };
                        callNext(0);
                };
        }
});

Reply via email to