"mehdi amini" <m@grauland.d e> wrote in message news:<bi******* ******@news.t-online.com>...
It looks great but would you (or others) mind to explain this peace of code
a bit more?
Sure; the goal was to expose the setTimeout method to the OP, and the
interest of using it recursively to form a chain of timed calls; if
you want to know more about this, check the archives at clj for
"setTimeout " and "setInterva l", especially Richard Cornford
'TimedQue', for instance at
<URL: http://groups.google.c om/groups?hl=en&lr =&ie=UTF-8&oe=UTF-8&selm=bdqk4h%2 4d3v%241%248302 bc10%40news.dem on.co.uk&rnum=3 >
As for the code, explanations follow.
//emulate the job part
function JobPart(){ /1(.+)+1/.test("011000") ; }
This part is used to emulate a job part; in reality you'd have a big
loop, such as
for(var ii=0; ii<bigNumber; ii++) {
doStuff(ii);
}
The idea is to execute 10 or more little loops instead of the big one,
so something like
function doStuffPart(sta rt, end){
for(var ii=start; ii<end; ii++){
doStuff(ii);
}
}
and call doStuffPart many times, with a timeout between each one in
order to give the browser the time to update the UI. The feasibility
depends on the stuff to be done :-)
The regexp used in the JobPart function is a killer for a regex
NFA-based engine, as javascript's. Adding more trailing zeros to the
string being tested can slow down the script, and I've found it a
quick way to emulate a consequent jobPart in a short line.
// emulate the job chain
var A_Jobs=[]
for(var ii=0; ii<100; ii++)
A_Jobs[ii]=JobPart;
An array of jobs; since there is only one function, this would be
neater to just call the function and throw the array away, but I had
before experimented with different jobPart funcs, and decided to leave
the array construction so that different JobParts could be called
without problem if needed.
The following part is more complicated, I've adopted a closure
approach, since I considered the two previous parts to be "only"
simple emulation and the following one to be the real issue (so
conception mattered) - moreover closures have been discussed a lot
recently and as a result I've come to use them quite often (thanks
Richard) :-)
To know more about closures, check the archives, especially the
following thread "Closures, what are they good for":
<URL: http://groups.google.c om/groups?hl=en&lr =&ie=UTF-8&oe=UTF-8&threadm=b8dsh d%24d46%241%248 302bc10%40news. demon.co.uk&rnu m=1&prev=/groups%3Fhl%3De n%26lr%3D%26ie% 3DUTF-8%26oe%3DUTF-8%26q%3Dclosure s%26btnG%3DGoog le%2BSearch%26m eta%3Dgroup%253 Dcomp.lang.java script>
// job controller
var Job = function() {
var ii=0, d=document;
var UserInform = {
start : function() { c("wait"); window.status=" 0%"; },
update : function(state) { window.status=s tate+"%"; },
stop : function() { c("default"); window.status=" "; }
};
var c=function(a){d ocument.body.st yle.cursor=a;};
return function (){
UserInform.star t();
A_Jobs[ii++]();
UserInform.upda te(Math.floor(i i*100/A_Jobs.length)) ;
if (ii<A_Jobs.leng th) setTimeout(argu ments.callee, 1);
else {
ii=0;
UserInform.stop ();
}
}
}();
</script>
The Job variable is assigned the _result_ of an anonymous function,
executed at the same time it is declared. This result appears to be a
function, but since this function is nested inside the executed one,
the local variables of the outer function are still available to the
inner function (the one that does the work), but completely hidden to
anything else - they are perfect private static members.
These members include "ii", used as an index for the JobParts array,
"d" as a pointer to document (keeping reference not only makes the
code faster and neater, but also easier to post in a NG, where you
have to limit code to 72 chars to avoid line breaks!).
UserInform is a simple object used as an interface to the UI, with
three methods (start, update and stop). The controller just calls the
appropriate methods to update the UI, if you want to remove the
terrible window.status with DHTML you just have to replace the content
of the methods.
"c" is a simple helper to update the cursor, as wanted by the OP.
The inner anonymous function (the one returned and being assigned the
the "Job" variable) does the whole job: lauching the job parts one
after the other, using private static vars to keep track of where it
is (it needs to keep the information outside of its own scope,
otherwise the info will be cleared as soon as the function has
executed). The setTimeout part is the real thing to understand, with
the function calling itself recursively (note how the scope chain
remains unaltered). The "1" timeout value will result in the function
being called as soon as possible (around 10msec in Win2k and 50ms on
Win98) - and this is enough to give the browser the opportunity make
the relevant UI updates and keep the script as fast as possible.
Of course adding such a "monitoring " feature will slow down the whole
script (be it table sorting, high calculations etc), but the benefit
for the user is invaluable in the end.
HTH
Yep.