Go Back   CodingForums.com > :: Client side development > JavaScript programming > Post a JavaScript

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Old 11-27-2002, 01:10 AM   PM User | #1
Algorithm
Regular Coder

 
Join Date: Jul 2002
Location: USA
Posts: 151
Thanks: 0
Thanked 0 Times in 0 Posts
Algorithm is an unknown quantity at this point
The Timer class, for object-oriented timeouts

The problems with the setTimeout and setInterval functions provided in Javascript are twofold. First, you can't call a local object method without losing your scope, and second, you can't pass objects to the function, since the function call is implemented as a string.

The Timer class solves these difficulties by employing a static array to store the parent object and function arguments until the function is called.

This class is provided as-is and pro bono, so go ahead and muck with it if you see things that could be done better.

Thanks to WA for giving me the idea for this (albeit indirectly)!

Updated 4/18/2003: Footprint decreased, minor code improvements.
Updated 5/3/2003: Minor comment clarification; no code changes.
Updated 5/10/2003: Minor code improvements.
Code:
// The constructor should be called with
// the parent object (optional, defaults to window).

function Timer(){
    this.obj = (arguments.length)?arguments[0]:window;
    return this;
}

// The set functions should be called with:
// - The name of the object method (as a string) (required)
// - The millisecond delay (required)
// - Any number of extra arguments, which will all be
//   passed to the method when it is evaluated.

Timer.prototype.setInterval = function(func, msec){
    var i = Timer.getNew();
    var t = Timer.buildCall(this.obj, i, arguments);
    Timer.set[i].timer = window.setInterval(t,msec);
    return i;
}
Timer.prototype.setTimeout = function(func, msec){
    var i = Timer.getNew();
    Timer.buildCall(this.obj, i, arguments);
    Timer.set[i].timer = window.setTimeout("Timer.callOnce("+i+");",msec);
    return i;
}

// The clear functions should be called with
// the return value from the equivalent set function.

Timer.prototype.clearInterval = function(i){
    if(!Timer.set[i]) return;
    window.clearInterval(Timer.set[i].timer);
    Timer.set[i] = null;
}
Timer.prototype.clearTimeout = function(i){
    if(!Timer.set[i]) return;
    window.clearTimeout(Timer.set[i].timer);
    Timer.set[i] = null;
}

// Private data

Timer.set = new Array();
Timer.buildCall = function(obj, i, args){
    var t = "";
    Timer.set[i] = new Array();
    if(obj != window){
        Timer.set[i].obj = obj;
        t = "Timer.set["+i+"].obj.";
    }
    t += args[0]+"(";
    if(args.length > 2){
        Timer.set[i][0] = args[2];
        t += "Timer.set["+i+"][0]";
        for(var j=1; (j+2)<args.length; j++){
            Timer.set[i][j] = args[j+2];
            t += ", Timer.set["+i+"]["+j+"]";
    }}
    t += ");";
    Timer.set[i].call = t;
    return t;
}
Timer.callOnce = function(i){
    if(!Timer.set[i]) return;
    eval(Timer.set[i].call);
    Timer.set[i] = null;
}
Timer.getNew = function(){
    var i = 0;
    while(Timer.set[i]) i++;
    return i;
}
Here's an example of the code in action:
Code:
function Ticker(){
    this.count = 0;
    this.timer = new Timer(this);
}
Ticker.prototype.tick = function(d){
    this.count+=d;
    window.status = ""+this.count;
    this.timer.setTimeout("tick", 1000, d);
}
                   
window.onload = function(){
    var ticker = new Ticker();
    ticker.tick(1);
}

Last edited by Algorithm; 05-10-2003 at 12:38 PM..
Algorithm is offline   Reply With Quote
Old 02-02-2003, 09:04 PM   PM User | #2
beetle
Senior Coder

 
Join Date: Aug 2002
Posts: 3,467
Thanks: 0
Thanked 0 Times in 0 Posts
beetle has a little shameless behaviour in the past
Hey Algorithm

I don't know if anyone else here uses this, but I've implemented it into a couple scripts I'm working on that are OO in nature. I wouldn't be able to do them without a OO-based timeout include, and this one works wonderfully.

Thanks for the great code!
__________________
My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
“Minds are like parachutes. They don't work unless they are open”
“Maturity is simply knowing when to not be immature”
beetle is offline   Reply With Quote
Old 02-05-2003, 03:07 AM   PM User | #3
Skyzyx
Regular Coder

 
Skyzyx's Avatar
 
Join Date: Aug 2002
Location: Silicon Valley, CA
Posts: 980
Thanks: 0
Thanked 0 Times in 0 Posts
Skyzyx is on a distinguished road
BTW, you CAN pass variables to setTimeout() and setInterval().

Code:
setTimeout('myFunction()', 1000, parameter1, parameter2, ..., parameter[n]);
But your code is still cool!
__________________

Creator of SimplePie and Tarzan AWS, co-founder of WarpShare, co-built the Y! Messenger website, usability-focused, and an INFJ personality.
Skyzyx is offline   Reply With Quote
Old 04-02-2003, 03:17 AM   PM User | #4
beetle
Senior Coder

 
Join Date: Aug 2002
Posts: 3,467
Thanks: 0
Thanked 0 Times in 0 Posts
beetle has a little shameless behaviour in the past
Skyzyx. I've never seen that, and neither of these pages indicate that.

Have you actually used this?
__________________
My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
“Minds are like parachutes. They don't work unless they are open”
“Maturity is simply knowing when to not be immature”
beetle is offline   Reply With Quote
Old 04-02-2003, 08:50 PM   PM User | #5
Roy Sinclair
Senior Coder

 
Join Date: Jun 2002
Location: Wichita
Posts: 3,881
Thanks: 0
Thanked 0 Times in 0 Posts
Roy Sinclair is an unknown quantity at this point
Quote:
Originally posted by Skyzyx
BTW, you CAN pass variables to setTimeout() and setInterval().

Code:
setTimeout('myFunction()', 1000, parameter1, parameter2, ..., parameter[n]);
But your code is still cool!
Sorry but that's a Netscape extension and it's not supported in IE. I may only be supported in Netscape 4, don't know if later versions of Netscape support it or not.
Roy Sinclair is offline   Reply With Quote
Old 04-02-2003, 09:51 PM   PM User | #6
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,509
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
Re: The Timer class, for object-oriented timeouts

Quote:
Originally posted by Algorithm
you can't pass objects to the function, since the function call is implemented as a string.
Yeah you can - I do this all the time:
Code:
var tempObj1,tempObj2,theTimer;
function someFunction(obj1,obj2)
{
    tempObj1 = obj1;
    tempObj2 = obj2;
    theTimer = setInterval("someFunction(tempObj1,tempObj2)",100);
}
It may be passed as a string, but it still evaluates as an object reference.
__________________
"Why bother with accessibility? ... Because deep down you know that the web is attractive to people who aren't exactly like you." - Joe Clark
brothercake is offline   Reply With Quote
Old 04-02-2003, 10:08 PM   PM User | #7
beetle
Senior Coder

 
Join Date: Aug 2002
Posts: 3,467
Thanks: 0
Thanked 0 Times in 0 Posts
beetle has a little shameless behaviour in the past
I think we've been talking about passing local variables, brothercake, at least I know I have. I mean, if you're using global variables there's no point in passing them at all
__________________
My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
“Minds are like parachutes. They don't work unless they are open”
“Maturity is simply knowing when to not be immature”
beetle is offline   Reply With Quote
Old 04-02-2003, 10:30 PM   PM User | #8
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeĺ, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enough
Didn't Alex post a nice and small way to do this some time ago? (Like when I last frequented this forum, before the change of name from WSAbstract to JS Kit...)
__________________
liorean <[lio@wg]>
Articles: RegEx evolt wsabstract , Named Arguments
Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards
liorean is offline   Reply With Quote
Old 04-19-2003, 01:28 AM   PM User | #9
Algorithm
Regular Coder

 
Join Date: Jul 2002
Location: USA
Posts: 151
Thanks: 0
Thanked 0 Times in 0 Posts
Algorithm is an unknown quantity at this point
Thanks for the great feedback, guys, and thanks especially to beetle for his heavy promotion of the class.

I've updated the code to remove the global array and decrease the class's footprint by half, as well as to make minor improvements throughout the class. The code should run cleaner now and with less unnecessary delay.

Any feedback on this new version would be more than appreciated.
Algorithm is offline   Reply With Quote
Old 04-19-2003, 02:03 AM   PM User | #10
beetle
Senior Coder

 
Join Date: Aug 2002
Posts: 3,467
Thanks: 0
Thanked 0 Times in 0 Posts
beetle has a little shameless behaviour in the past
Great! I'll d/l it right away.

No implementation changes, right? :P

Greak work
__________________
My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
“Minds are like parachutes. They don't work unless they are open”
“Maturity is simply knowing when to not be immature”
beetle is offline   Reply With Quote
Old 05-09-2003, 11:03 PM   PM User | #11
Tim Scarfe
New to the CF scene

 
Join Date: Apr 2003
Location: London
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Tim Scarfe is an unknown quantity at this point
Nice class.

Shame you are using strings on the setTimeout instead of passing a function reference.

Any syntax errors would not be clear to the developer as the string is evaluated at runtime. The code is ugly and there is simply no need for this uglyness. Simple scope guys..

We have commented on the script @ DC:

http://www.dhtmlcentral.com/forums/t...TOPIC_ID=17585
Tim Scarfe is offline   Reply With Quote
Old 05-10-2003, 01:51 AM   PM User | #12
Algorithm
Regular Coder

 
Join Date: Jul 2002
Location: USA
Posts: 151
Thanks: 0
Thanked 0 Times in 0 Posts
Algorithm is an unknown quantity at this point
Quote:
Originally posted by Tim Scarfe
Shame you are using strings on the setTimeout instead of passing a function reference.

Any syntax errors would not be clear to the developer as the string is evaluated at runtime. The code is ugly and there is simply no need for this uglyness. Simple scope guys..
The problem is, there's numerous pitfalls involved in attempting to use a function reference. Passing it directly to window.setTimeout would nullify the scope (not to mention making the code inoperable in several browsers). Storing the reference for the duration would necessitate appending a temporary value to the parent object, and -- if at all possible -- altering external objects is something I emphatically want to avoid. The only other option would be to pass the method name along with the reference, which I consider redundant.

I agree that, if it were workable, passing a reference would be preferable to passing the name; however, I see no method in which it would work without alienating browsers or altering external objects. Feel free to prove me wrong.
Algorithm is offline   Reply With Quote
Old 05-10-2003, 04:34 AM   PM User | #13
Tim Scarfe
New to the CF scene

 
Join Date: Apr 2003
Location: London
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Tim Scarfe is an unknown quantity at this point
Quote:
The problem is, there's numerous pitfalls involved in attempting to use a function reference. Passing it directly to window.setTimeout would nullify the scope (not to mention making the code inoperable in several browsers). Storing the reference for the duration would necessitate appending a temporary value to the parent object, and -- if at all possible -- altering external objects is something I emphatically want to avoid. The only other option would be to pass the method name along with the reference, which I consider redundant.
Sorry, No. This is just wrong wrong wrong, and doesn't entirely make sense. Apart from this bit:

Quote:
(not to mention making the code inoperable in several browsers).
*Scope is not lost
*You don't need to make any objects or properties or whatever you were saying
*Performance is greater with functions
*You want object instance code running in global scope, duh?
*You want to discover syntax errors at runtime?
*You want ugly code in strings? i.e. clearer code
*code is more encapsulated
*more clever things like applying functions possible

What you have done is just like using eval(), and we all know eval is evil, or you SHOULD.

As I said on DC, IE5.00 and some really ancient browsers have problems with this, but it's really a no brainer argument as proper scope is used in all properly written DHTML classes.

I'm way too tired to proove this now and I need sleep, but I have flagged this up on my to-do list for tommorrow, and it's a high priority! I've done well to post this much after the crazy night I've just returned from

In the mean time, I will quote Erik Advisson of webfx.eae.net fame:

Quote:
// 27/05/2002 14:14

How come people keep using eval and the setTimeout eval counterpart. JS is a language that supports higher order functions and thus the best way to use setTimeout is to use the version that uses this feature. Compare the following two cases and decide for yourself which one to prefer.

// alt. 1
// non global code
var obj = getSomeObject();
makeObjectGloballyAccessible(obj); // in your case you put it in a global array
window.setTimeout(getGlobalAccessCode(obj) + ".someMethod()", t);

// alt. 2
// non global code
var obj = getSomeObject();
window.setTimeout(function() { obj.someMethod(); }, t);

The second one does not require any global references to objects and it allows you to use write code instead of strings. There are quite a few reasons to use alt. 2:

* Allows anonymous code, i.e. non-global objects
* Garbage collection can correctly dispose objects because there are no global references
* Easier to write
* Syntax errors are caught at startup.
* No eval. Evals are slow and error prone. Eval happen at runtime and cannot be compiled/checked. Even in a non compiled environment these are significantly slower than non-evaluated code.
* No need for code that makes object available as globals and no need for code to reference the global object

There is one downside to using the higher order function version of setTimeout and that is that it does not work in Netscape 3, IE3 (4?) and crashes IE5.0 (without any fixes, 5.01 works fine). But then again, targeting IE5.0 and NN4 and any of the old, non-dom browsers is not the choice of a true visionary :-)

erik
Tim Scarfe is offline   Reply With Quote
Old 05-10-2003, 07:20 AM   PM User | #14
beetle
Senior Coder

 
Join Date: Aug 2002
Posts: 3,467
Thanks: 0
Thanked 0 Times in 0 Posts
beetle has a little shameless behaviour in the past
Great arguments et points Tim - but I think you could step off the pedastal a bit (and Eric too)

Ignoring the fact that most people writing javascript aren't programmers is a bit pious. The fact of the matter is, many people (20%+) still use IE5 -- whether 5.0 or 5.01 I do not know, but when working for a client and not oneself, we have to keep these things in mind regardless of our capacity to be a "visionary".

This is great information to have and I thank you for that - I just think you could have presented your case with a bit more tact.

I don't think any more explanation is needed -- anyone that can grasp what scope is and understands OO js should have no trouble seeing what's going on in your last post.

Oh, and welcome to codingforums.com
__________________
My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
“Minds are like parachutes. They don't work unless they are open”
“Maturity is simply knowing when to not be immature”

Last edited by beetle; 05-10-2003 at 07:23 AM..
beetle is offline   Reply With Quote
Old 05-10-2003, 11:06 AM   PM User | #15
WA
Administrator


 
Join Date: Mar 2002
Location: North America
Posts: 2,347
Thanks: 1
Thanked 12 Times in 12 Posts
WA will become famous soon enough
Hi Tim:
Thanks for the info- it's certainly useful, and we do appreciate it. Personally though, the fact that this technique doesn't work in IE5 means I wouldn't even consider using it for now, since as someone mentioned, usability to me is just as important as elegance, if not more so.

Again, it's great information, though I may need to go back and study it some more to even get it.
__________________
- George
- JavaScript Kit- JavaScript tutorials and 400+ scripts!
- JavaScript Reference- JavaScript reference you can relate to.
WA is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 12:20 AM.

Home - Contact Us - Archives - Link to CF - Resources - Top 

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.