1) CODE TITLE: TimeoutChainer
2) AUTHOR NAME/NOTES: Trinithis
3) DESCRIPTION: Replaces for-loop closures to chain window.setTimeout()'s among other things.
4) URL TO CODE: http://trinithis.awardspace.com/Time...eoutChainer.js
Demos:
http://trinithis.awardspace.com/Time...ner/demo1.html
http://trinithis.awardspace.com/Time...ner/demo2.html
I made the TimeoutChainer class to avoid excessive closure use when staging a sequence of setTimeout()'s. It is supposed to simplify creating such a task.
-------------------------------
How To:
This is the default object used for TimeoutChainer's object argument. When calling the constructor, you send in one argument that is an object. If that object has a property name that is the same as in the above object, TimeoutChainer will use it's value. If it does not have a corresponding property, then the default object's property value will be used instead.Code://Object Arguments
{
callback: null,
context: null,
interval: 0,
delay: -1, //translates to this.interval
numTimes: 1,
args: [],
runAfter: null
}
- callback: The function to execute at each timeout. You must supply this argument. It may either be a function reference or a string.
- context: An object reference which the callback uses for the
thiskeyword. Primarily will be used for method callbacks. Use null if there is no need.- interval: The time delay between each callback.
- delay: When to call the first callback. After that times depend on
interval. Negative values get translated into the interval time.- numTimes: The number of times to call the callback function.
- args: Holds the arguments
callbackwill use.- runAfter: If an object is specified, will only start the timeouts when that object tells it to start. If the object is a TimeoutChainer (TC), THIS will automatically start its timeouts when TC finishes its timeouts. (
delayandintervalstill come into effect.) Demo1 makes use of this.
Among other things, a variety of properties and methods are also avaliable. It is safe to change most of the supplied "object arguments" whenever you want (... as long as your logic is done correctly). If you change the following properties:
- callback: Must be a function reference. Cannot use a string this time.
- numTimes, remaining, completed: Once the timeouts stop and you change these, you have to initiate the timeouts again through the
chainTimeout()method. Note: Onlyremainingis actually used to determine whether or not to stop the timeouts, and that happens when it reaches 0.- runAfter: Changing this may cause serious bugs. Leave it alone unless you understand how the constructor uses it.
Methods:
- clear(): Clears any existing timeout and will prevent further from being issued until
chainTimeout()is called. Setsremainingto 0. Will not change completed. This method will also invoke any TimeoutChainers waiting on this to complete.- chainTimeout(): Will initiate the TimeoutChainer. This will always chain at least one timeout even if
remainingequals 0. Invoking this method might cause bugs if you supplied a TimeoutChainer torunAfterin the constructor or if you call it while it is still issuing timeouts. You probably should create a new TimeoutChainer instead of calling this method.
Static Member:
- TimeoutChainer.SELF: For the
argsproperty of the object arguments, you can use this solitary enum constant. The constructor will translate it into a reference to itself. Only use during the constructor. In addition, there really is no need since you can supply an actual reference after constructed. Demo2 makes use of this static member.
-------------------------------
Example used in demo1:
Example used in demo2:Code:var list = document.getElementById("list");
list.appendText = function(s) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(s));
list.appendChild(li);
}
var tc = new TimeoutChainer({
callback: "appendText",
args: [{i:1, toString:function(){return String(this.i++)}}],
context: list,
interval: 100,
numTimes: 10
});
new TimeoutChainer({
callback: list.appendText,
args: [{i:10, toString:function(){return String(this.i--)}}],
context: list,
interval: 100,
delay: 100,
numTimes: 10,
runAfter: tc
});
Code://Just think of TextFormatter as a nice way to print stuff on the screen
var tf1 = new TextFormatter(document.getElementById("div1")).setFontFamily("monospace");
var tf2 = new TextFormatter(document.getElementById("div2")).setFontFamily("monospace");
function write(s, tc, tf) {
tf.println(tc.completed + ":" + s);
}
function clearTC(tc) {
tc.clear();
}
setTimeout(
bundleFunction(
null, clearTC, new TimeoutChainer({
numTimes: 10, interval: 100, startDelay: 200,
callback: write, args: ["hi", TimeoutChainer.SELF, tf1]
})
), 450
);
setTimeout(
bundleFunction(
new TimeoutChainer({
numTimes: 10, interval: 100,
callback: "println", args: [{
i: 1,
toString: function() {
return this.i++ + ":bye";
}
}], context: tf2
}), "clear"
), 550
);
