Subj : Re: Threading in JavaScript To : comp.lang.javascript,netscape.public.mozilla.jseng From : Steve van Dongen Date : Sun Feb 02 2003 10:57 pm On Sun, 02 Feb 2003 14:39:49 +0000, Gordan wrote: >Fox wrote: > >> while you are right that there is no guarantee that execution of functions >> will happen as precisely timed, you have no guarantee of that in Java >> either -- although you have a better "expectation" of precision if you set >> the priority to high [around 10, depending on what the sandbox will allow, >> you still only get to *request* priority!]. > >Yes, but you also HAVE a guarantee that the functions will execute >sequentially, NOT in parallel. Or am in error there? > >> Most people don't get threads in JavaScript. You have two options: >> setTimeout (a one time execution) or setInterval (for repetitive >> executions). > >Yeah, I figured that this was the only construct in JS that would even >theoretically allow for threading (no fork() ;-) ). > >> The thing you have to remember with JS is that it's not that fast -- so >> don't overburden the threads. > >It's not all that slow if done properly, either. Manipulating the page and >parsing DOM can be slow, but I have found it to be on the par with other >inpterpreted languages. > >> How to run multiple "asynchronous" threads? >> >> maintain multiple variables, or an array of timer. To make demonstration >> easy, I'll use multiple variables... >> >> >> var timer_for_f_one = null; >> var timer_for_f_two = null; >> var timer_for_f_three = null; > >[snip] > >> timer_for_f_one = setTimeout("f_one()", 500); >> timer_for_f_two = setTimeout("f_two()", 750); >> timer_for_f_three = setTimeout("f_three()","333"); > >> function >> f_one() >> { >> // do stuff every 1/2 second >> timer_for_f_one = setTimeout("f_one()", 500); // repeat >> } >> >> function >> f_two() >> { >> // do stuff every 3/4 second >> timer_for_f_two = setTimeout("f_one()", 750); // repeat >> } >> >> function >> f_three() >> { >> // do stuff every 1/3 second >> timer_for_f_three = setTimeout("f_one()", 333); // repeat >> } > >So, each function recursively schedules itself for the next run. OK, I >understand that. > >> If you use setTimeout without saving it's reference, then the browser will >> use a "blind >> reference" to save the timeout ref. The problems with this, you have >> already discovered. > >I have just tried the above solution as you described it. I am still unable >to get parallel execution to work. I have a test page that has two text >boxes textbox1 and textbox2. There are two functions running through loops >that assign the value of the iterator to textbox1.value and textbox2.value. > >Even with saving the return of setTimeout to a variable (I used a global >scope array), they STILL execute one AFTER the other. The two loops do not >interleave, and the second text box still doesn't update until the first >one is completely finished. > >I have tried this on both Mozilla and IE, and both behave the same way. Have >I missed something? Yeah, kind of... > for (i = 0; i < 100; i++) > { > ThreadText1.value = i; > > // I'm told adding setTimeout() in loops helps > // with giving the browser a bit of time to > // catch up... That's not quite right. Using setTimeout *INSTEAD* *OF* or in conjunction with a loop will give the browser a bit of time to catch up. setTimeout only schedules some script to run at some point in the future; you only give the browser time to do something else if you don't do something else yourself. > if (DelayLoop[0]) > { > clearTimeout(DelayLoop[0]); > } > > DelayLoop[0] = setTimeout("", 0); > } > } I your code, your setTimeout is really not doing anything. Your first for loop runs, burning up all the available processor time, and afterwards your other for loop runs. The idea is to have your Thread1 and Thread2 functions do only a little bit of real work, then use setTimeout to run them again a little later. I changed Thread1 to do 1 iteration of the "loop" per function call and Thread2 to do 10 iterations per function call. // Global Variables var ThreadHandle = new Array(); function ThreadTest() { ThreadHandle[0] = setTimeout("Thread1(0)", 20); ThreadHandle[1] = setTimeout("Thread2(0)", 10); } function Thread1(i) { var ThreadText1 = document.getElementById("ThreadText1"); if (i < 1000) { ThreadText1.value = i; ThreadHandle[0] = setTimeout("Thread1(" + (i+1) + ")", 20); } } function Thread2(i) { var ThreadText2 = document.getElementById("ThreadText2"); if (i < 10000) { for (var j=0; i<10000 && j<10; i++, j++) ThreadText2.value = i; ThreadHandle[1] = setTimeout("Thread2(" + (i+1) + ")", 10); } } function Body_onUnload() { for (var i=0; i