CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Web 开发 >  JavaScript

在javascript中用command模式模拟多线程

楼主emu_ston(祝福后山)2005-06-08 20:34:45 在 Web 开发 / JavaScript 提问

以前也看过有高手在wsh上可以创建thread对象,但是毕竟不是常规手段,我们做web应用一般没有本地访问权限的,用activex的没试过,毕竟也不是javascript方式。  
  以前我们解决这样的问题都是针对具体问题写一段代码来模拟多线程的,但是由于往往要对没个线程单独编码,这样的代码十分冗长(http://www.blogjava.net/Files/emu/counting.zip)。学习设计模式的时候就曾经考虑过在javascript中实用command模式来更好的模拟多线程,但是一直没有付诸实施,今天既然想起来了就试试看:  
   
  <html>  
  <head>  
  <title>emu   --   用command模式模拟多线程</title>  
  </head>  
  <body>  
  <SCRIPT   LANGUAGE="JavaScript">  
  <!--  
  var   commandList   =   [];  
  function   executeCommands(){  
  if   (commandList.length>0){  
  commandList.shift()();  
   
  }  
  }  
   
  function   startNewTask(){  
  var   resultTemp   =   document.createElement("span");  
  document.body.insertBefore(resultTemp,document.body.lastChild);  
  document.body.insertBefore(document.createElement("br"),document.body.lastChild);  
  resultTemp.innerText   =   0;  
          commandList.push(function(){simThread(resultTemp,0);});  
  }  
   
  function     simThread(temp,n){  
  temp.innerText   =   temp.innerText-(-n);  
  if   (n<1000)  
  commandList.push(function(){simThread(temp,++n);});  
  else{  
  document.body.removeChild(temp.nextSibling);  
  document.body.removeChild(temp);  
  }  
  }  
   
  window.onload   =   function(){setInterval("executeCommands()",1);}  
   
  //-->  
  </SCRIPT>  
  <button   onclick="startNewTask()">start</button>  
   
  <BR><BR>  
  </body>  
  </html>  
   
  注意第11行。javascript里面函数也是对象,所以就没有必要把函数调用包装到do或者execute方法里面了,直接用()就可以让函数对象运行起来:  
  commandList.shift()();  
   
   
  shift函数是javascript中array对象的函数,可是IE5居然没有定义,不过我曾经实现过IE5上面没实现的全部array函数,可以用这个脚本来增强IE5:   http://www.blogjava.net/Files/emu/IE5ArrayFunctions.zip  
  问题点数:200、回复次数:67Top

1 楼ttyp(@http://www.cnblogs.com/ttyp/)回复于 2005-06-08 21:13:12 得分 1

不错!!Top

2 楼cslren(位流)回复于 2005-06-08 21:22:39 得分 1

支持你Top

3 楼fason(咖啡人生)回复于 2005-06-08 22:21:38 得分 1

:_)Top

4 楼leojay1(绯村剑心)回复于 2005-06-08 23:06:51 得分 1

markTop

5 楼emu_ston(祝福后山)回复于 2005-06-09 09:18:14 得分 0

改进了一下,现在允许在一个运行周期里面运行多个command,同时提供了对线程延迟的支持(见executeCommands函数中)。任务是计算1+2+3...+1000累加的结果。现在让每个任务运行完成后延迟2秒再清楚自己的运行结果。点击一次鼠标就建立一个线程。  
   
  <html>  
  <head>  
  <title>emu   --   用command模式模拟多线程</title>  
  </head>  
  <body>  
  <SCRIPT   LANGUAGE="JavaScript">  
  <!--  
   
   
  if   (Array.prototype.shift==null)  
  Array.prototype.shift   =   function   (){  
  var   rs   =   this[0];  
  for   (var   i=1;i<this.length;i++)   this[i-1]=this[i]  
  this.length=this.length-1  
  return   rs;  
  }  
  if   (Array.prototype.push==null)  
  Array.prototype.push   =   function   (){  
  for   (var   i=0;i<arguments.length;i++)   this[this.length]=arguments[i];  
  return   this.length;  
  }  
   
  var   commandList   =   [];  
  var   nAction   =   0;//控制每次运行多少个动作  
  var   functionConstructor   =   function(){}.constructor;  
  function   executeCommands(){  
  for   (var   i=0;i<nAction;i++)  
  if   (commandList.length>0){  
  var   command   =   commandList.shift();  
  if   (command.constructor   ==   functionConstructor)  
  if   (command.scheduleTime   ==   null   ||   new   Date()-command.scheduleTime>0)  
  command();  
  else  
  commandList.push(command);  
  }  
  }  
   
   
  function   startNewTask(){  
  var   resultTemp   =   document.getElementById("sampleResult").cloneNode(true);  
  with   (resultTemp){  
  id="";style.display="block";style.color=Math.random()*(2<<23.5);  
  }  
  document.body.insertBefore(resultTemp,document.body.lastChild);  
          commandList.push(function(){simThread(resultTemp,1);});  
  nAction++;  
  }  
   
  function     simThread(temp,n){  
  if   (temp.stop)   n--;  
  else   temp.innerText   =   temp.innerText-(-n);  
  if   (n<1000)  
  commandList.push(function(){simThread(temp,++n)});  
  else{  
  var   command   =   function(){document.body.removeChild(temp);;nAction--;};  
  command.scheduleTime   =   new   Date()-(-2000);  
  commandList.push(command);  
  }  
  }  
   
  window.onload   =   function(){setInterval("executeCommands()",1);}  
  //-->  
  </SCRIPT>  
  <button   onclick="startNewTask()">开始新线程</button>  
   
  <BR><BR>  
  <div   id=sampleResult   onmouseover="this.stop=true"   onmouseout="this.stop=false"   style="display:none;cursor:hand">0</div>  
  </body>  
  </html>  
   
  看了一下cpu占用,开1个任务和10个任务的cpu占用基本上没有区别。其实真正用在任务上的cpu时间是很少的。Top

6 楼emu_ston(祝福后山)回复于 2005-06-09 09:18:36 得分 0

改进了一下,现在允许在一个运行周期里面运行多个command,同时提供了对线程延迟的支持(见executeCommands函数中)。任务是计算1+2+3...+1000累加的结果。现在让每个任务运行完成后延迟2秒再清楚自己的运行结果。点击一次鼠标就建立一个线程。  
   
  <html>  
  <head>  
  <title>emu   --   用command模式模拟多线程</title>  
  </head>  
  <body>  
  <SCRIPT   LANGUAGE="JavaScript">  
  <!--  
   
   
  if   (Array.prototype.shift==null)  
  Array.prototype.shift   =   function   (){  
  var   rs   =   this[0];  
  for   (var   i=1;i<this.length;i++)   this[i-1]=this[i]  
  this.length=this.length-1  
  return   rs;  
  }  
  if   (Array.prototype.push==null)  
  Array.prototype.push   =   function   (){  
  for   (var   i=0;i<arguments.length;i++)   this[this.length]=arguments[i];  
  return   this.length;  
  }  
   
  var   commandList   =   [];  
  var   nAction   =   0;//控制每次运行多少个动作  
  var   functionConstructor   =   function(){}.constructor;  
  function   executeCommands(){  
  for   (var   i=0;i<nAction;i++)  
  if   (commandList.length>0){  
  var   command   =   commandList.shift();  
  if   (command.constructor   ==   functionConstructor)  
  if   (command.scheduleTime   ==   null   ||   new   Date()-command.scheduleTime>0)  
  command();  
  else  
  commandList.push(command);  
  }  
  }  
   
   
  function   startNewTask(){  
  var   resultTemp   =   document.getElementById("sampleResult").cloneNode(true);  
  with   (resultTemp){  
  id="";style.display="block";style.color=Math.random()*(2<<23.5);  
  }  
  document.body.insertBefore(resultTemp,document.body.lastChild);  
          commandList.push(function(){simThread(resultTemp,1);});  
  nAction++;  
  }  
   
  function     simThread(temp,n){  
  if   (temp.stop)   n--;  
  else   temp.innerText   =   temp.innerText-(-n);  
  if   (n<1000)  
  commandList.push(function(){simThread(temp,++n)});  
  else{  
  var   command   =   function(){document.body.removeChild(temp);;nAction--;};  
  command.scheduleTime   =   new   Date()-(-2000);  
  commandList.push(command);  
  }  
  }  
   
  window.onload   =   function(){setInterval("executeCommands()",1);}  
  //-->  
  </SCRIPT>  
  <button   onclick="startNewTask()">开始新线程</button>  
   
  <BR><BR>  
  <div   id=sampleResult   onmouseover="this.stop=true"   onmouseout="this.stop=false"   style="display:none;cursor:hand">0</div>  
  </body>  
  </html>  
   
  看了一下cpu占用,开1个任务和10个任务的cpu占用基本上没有区别。其实真正用在任务上的cpu时间是很少的。Top

7 楼DuJianDong(翼)回复于 2005-06-09 11:06:04 得分 1

markTop

8 楼emu_ston(祝福后山)回复于 2005-06-09 11:16:56 得分 0

改了一下,现在可以在firefox下面运行了:  
   
  <html>  
  <head>  
  <title>emu   --   用command模式模拟多线程</title>  
  </head>  
  <body>  
  <SCRIPT   LANGUAGE="JavaScript">  
  <!--  
   
   
  if   (Array.prototype.shift==null)  
  Array.prototype.shift   =   function   (){  
  var   rs   =   this[0];  
  for   (var   i=1;i<this.length;i++)   this[i-1]=this[i]  
  this.length=this.length-1  
  return   rs;  
  }  
  if   (Array.prototype.push==null)  
  Array.prototype.push   =   function   (){  
  for   (var   i=0;i<arguments.length;i++)   this[this.length]=arguments[i];  
  return   this.length;  
  }  
   
  var   commandList   =   [];  
  var   nAction   =   0;//控制每次运行多少个动作  
  var   functionConstructor   =   function(){}.constructor;  
  function   executeCommands(){  
  for   (var   i=0;i<nAction;i++)  
  if   (commandList.length>0){  
  var   command   =   commandList.shift();  
  if   (command.constructor   ==   functionConstructor)  
  if   (command.scheduleTime   ==   null   ||   new   Date()-command.scheduleTime>0)  
  command();  
  else  
  commandList.push(command);  
  }  
  }  
   
   
  function   startNewTask(){  
  var   resultTemp   =   document.getElementById("sampleResult").cloneNode(true);  
  with   (resultTemp){  
  id="";style.display="block";style.color=(Math.floor(Math.random()*   (1<<23)).toString(16)+"00000").substring(0,6);  
  }  
  document.body.insertBefore(resultTemp,document.body.lastChild);  
          commandList.push(function(){simThread(resultTemp,1);});  
  nAction++;  
  }  
   
  function     simThread(temp,n){  
  if   (temp.stop)   n--;  
  else   temp.innerHTML   =   temp.innerHTML   -   (-n);  
  if   (n<1000)  
  commandList.push(function(){simThread(temp,++n)});  
  else{  
  var   command   =   function(){document.body.removeChild(temp);;nAction--;};  
  command.scheduleTime   =   new   Date()-(-2000);  
  commandList.push(command);  
  }  
  }  
   
  window.onload   =   function(){setInterval("executeCommands()",1);}  
  //-->  
  </SCRIPT>  
  <button   onclick="startNewTask()">开始新线程</button>  
   
  <BR><BR>  
  <div   id=sampleResult   onmouseover="this.stop=true"   onmouseout="this.stop=false"   style="display:none;cursor:hand">0</div>  
  </body>  
  </html>  
   
  主要是改了:   else   temp.innerHTML   =   temp.innerHTML   -   (-n);  
  和:style.color=(Math.floor(Math.random()*   (1<<23)).toString(16)+"00000").substring(0,6);Top

9 楼meizz(梅花雪)回复于 2005-06-09 11:17:27 得分 20

emu   的东东必是精品,   支持地说Top

10 楼emu_ston(祝福后山)回复于 2005-06-09 13:37:55 得分 0

在firefox下面屏幕闪的很厉害,估计是firefox为了支持多平台没有调用directX写屏造成屏幕显示不流畅,有没有高手能解决这个问题呢?Top

11 楼ttyp(@http://www.cnblogs.com/ttyp/)回复于 2005-06-09 14:51:18 得分 10

屏幕显示就不要研究了,要研究研究线程的其他功能,如暂停,停止,重新开始,同步,信号等,并加以封装,呵呵Top

12 楼emu_ston(祝福后山)回复于 2005-06-09 15:12:51 得分 0

脚本语言而已啦,有必要做的那么复杂吗,主要是想在不失去响应的情况下提供一个后台运算的能力。Top

13 楼ttyp(@http://www.cnblogs.com/ttyp/)回复于 2005-06-09 15:19:57 得分 1

玩就玩个彻底了,至少你可以让多线程不止是运算,至少可以让调用更简单点吧。像JS做的星际里就有多线程的部分Top

14 楼runmin()回复于 2005-06-09 16:41:18 得分 1

活活,搅和一下Top

15 楼satans18((何畏)(只要你过得比我好))回复于 2005-06-09 17:26:29 得分 1

厉害~向高手学习!!   :)Top

16 楼applebomb(袋装苹果)回复于 2005-06-09 18:06:29 得分 1

mark一下Top

17 楼ken2002(尖刀)回复于 2005-06-09 18:14:32 得分 1

收藏了Top

18 楼rightyeah(众妙之门)回复于 2005-06-10 08:22:00 得分 10

说白了就算多任务的队列化,想法不错,效果也还行,不过算不得厉害Top

19 楼patchclass(黑翼)回复于 2005-06-10 08:59:41 得分 1

markTop

20 楼s_phoenix()回复于 2005-06-10 09:00:25 得分 1

学习!Top

21 楼LGEN()回复于 2005-06-10 10:02:27 得分 0

呵呵程序太多,看不懂,能否说一下思想和原理。Top

22 楼LGEN()回复于 2005-06-10 10:10:52 得分 10

其实不能算是多线程,只是放一堆函数在数组里,然后一个一个执行而已。  
  如果你的每个执行的函数都是死循环,而你的程序能让它们都执行,这才是多线程初步。  
  Top

23 楼emu_ston(祝福后山)回复于 2005-06-10 10:10:57 得分 0

其实command模式只是用来模拟多线程而已,并不是真的实现了多线程,象暂停,重新开始,同步,信号这些当然也只能模拟实现。象我上面的代码看起来都可以暂停(鼠标指向一个任务的时候它就暂停运算了),重新开始(鼠标移开),schedule(一个任务结束后我安排它延迟两秒后把结果擦除)。  
   
  至于线程间的通讯和同步等高级功能,就算在java里面也不是那么简单的,君不见jdk每次升级往往都会在这方面做一些增强,网上杂志上讨论这个话题的文章也铺天盖地。用脚本来模拟这个东西一是做不好,二是实用性不强,做出来了多半也就是“玩的彻底”一点而已。Top

24 楼dh20156(风之石)回复于 2005-06-10 10:15:51 得分 1

学习,接分!Top

25 楼a040liutao(冬之心)回复于 2005-06-10 10:25:06 得分 0

顺便用多线程帮我解决这个问题吧,异步带回的HTML代码写到DIV中去   但两个函数同时执行时第一个会写不了,因为第2个没等第一个返回HTML代码就已经执行了就中断了第一个,代码如写  
   
  <script   language="javascript">  
  /****************************************************************  
  *   函数名:fnDo  
  *   功能描述:向指定的DIV/SPAN中写入异步带回的HTML代码  
  *   输入:  
  *   版本:2005-05-27   by   lt  
  /***************************************************************/  
  function   fnDo(ID,sDiv,sUrl)  
  {  
    sDiv.innerHTML   =   "Loading..."  
  xmlhttp   =   new   ActiveXObject("Msxml2.XMLHTTP");  
  var   xmlDom   =   new   ActiveXObject("Msxml2.DOMDocument");                    
          var   strURL   =   sUrl   +   ID;  
                   
          xmlhttp.Open("POST",strURL   ,   true);  
          xmlhttp.onreadystatechange   =   function(){  
  var   state   =   xmlhttp.readyState;  
   
  var   xmlDom   =   new   ActiveXObject("Msxml2.DOMDocument");  
   
  if   (state   ==   4)  
  {  
  xmlDom.loadXML(xmlhttp.responseXML.xml);  
        //alert(xmlDom.documentElement.selectSingleNode("//objXML").text)  
  var   getInfo   =   xmlDom.documentElement.selectSingleNode("//objXML").text;  
  sDiv.innerHTML   =   getInfo  
  }                  
  };  
          xmlhttp.Send(xmlDom);  
  return   1;  
  }  
  //--------------------------------------------------------  
  </script>  
  <div   id="divCategroy"></div>  
  <div   id="divContent"></div>  
  <script   language="javascript">  
  fnDo(0,divCategroy,"getcategory.asp?ID=")  
  fnDo(0,divContent,"getcategory.asp?ID=")  
  </script>  
  Top

26 楼JK_10000(JK)回复于 2005-06-10 10:46:10 得分 20

回复人:   emu_ston(吃的就是没文化的亏)   (   )   信誉:127     2005-06-10   10:10:00     得分:   0      
  "其实command模式只是用来模拟多线程而已,并不是真的实现了多线程"  
   
  ----  
  不少朋友喏喏称是,所以正在怀疑自己呢,  
  function     simThread(temp,n){  
  在这一句后加了一句:  
          if(Math.random()>0.99)   alert();  
  测试结果分明就是单线程啊    
   
  捊须深思中。。。。  
  Top

27 楼JK_10000(JK)回复于 2005-06-10 10:56:31 得分 20

虽说script本身不支持多线程  
  但是多个窗口里的script可以同时运行,也可以当多线程看,  
  还有window.showModelessDialog()它事实是也是多提供一个线程。  
   
  回复人:   a040liutao(冬之心)   (   )   信誉:100     2005-06-10   10:25:00     得分:   0      
  的问题,可以参考:  
  http://jkisjk.vip.sina.com/html/getDataFromServer.htm   的第一种方式Top

28 楼patchclass(黑翼)回复于 2005-06-10 12:36:14 得分 10

好像可以利用iframe来模拟多线程的,学习楼主的办法Top

29 楼emu_ston(祝福后山)回复于 2005-06-10 13:40:43 得分 0

用iframe啊?倒没想过。Top

30 楼a040liutao(冬之心)回复于 2005-06-10 14:52:26 得分 1

JK_10000(JK)     你给的地址打不开Top

31 楼emu_ston(祝福后山)回复于 2005-06-13 18:53:47 得分 0

试验了一下,iframe只能用来建立新的变量命名空间,却没有办法创建互不干扰的进程,一个iframe里面在执行运算任务的时候,其他的框架和主框架全部都被堵塞住了,没有办法实现上面的功能:  
   
  <html>  
  <head>  
  <title></title>  
  </head>  
  <body>  
  <button   onclick="newTask()">new   task</button>  
  <SCRIPT   LANGUAGE="JavaScript">  
  <!--  
  var   framesCount   =   0;  
  function   newTask(){  
  var   elm   =   document.createElement("iframe");  
  document.body.insertBefore(elm);  
  elm.style.display="none";  
  framesCount++;  
  document.frames[framesCount-1].document.write("<script>for   (var   i=0,n=0;i<=1000000;n+=i++);alert(n)<\/script>")  
  }  
  //-->  
  </SCRIPT>  
  </body>  
  </html>  
   
  点击按钮的时候开始执行运算,在运算结束前没有办法再点击一次按钮来开启一个新线程的。  
  modaldialog是肯定会堵塞主窗口的。开新窗口还有点用:  
  <html>  
  <head>  
  <title></title>  
  </head>  
  <body>  
  <SCRIPT   LANGUAGE="JavaScript">  
  <!--  
  function   newTask(left){  
  var   win   =   window.open("","","top=300,height=100,status=yes,width=300,left="+left);  
  win.document.write("<script>setTimeout('for   (var   i=0,n=0;i<=10001;n+=i++)status=n;',1000)<\/script>")  
  }  
  newTask(0);  
  newTask(330);  
  newTask(660);  
  //-->  
  </SCRIPT>  
  </body>  
  </html>Top

32 楼emu_ston(祝福后山)回复于 2005-06-13 19:03:21 得分 0

演示iframe确实会相互堵塞的一个更好的例子:  
   
  <html>  
  <head>  
  <title></title>  
  </head>  
  <body>  
  <SCRIPT   LANGUAGE="JavaScript">  
  <!--  
  var   count1=0;  
  var   count2=0;  
  var   elm   =   document.createElement("iframe");  
  document.body.insertBefore(elm);  
  elm.style.display="none";  
  document.frames[0].document.write("<script>setTimeout(\"for   (var   i=0,n=0;i<=10001;n+=i++){parent.count1=n;parent.status=parent.count1+'   -   '+parent.count2};\",1000)<\/script>")  
   
  var   elm   =   document.createElement("iframe");  
  document.body.insertBefore(elm);  
  elm.style.display="none";  
  document.frames[1].document.write("<script>setTimeout(\"for   (var   i=0,n=0;i<=10001;n+=i++){parent.count2=n;parent.status=parent.count1+'   -   '+parent.count2};\",1000)<\/script>")  
  //-->  
  </SCRIPT>  
  </body>  
  </html>Top

33 楼HLis(就是 HLis ~~)回复于 2005-06-13 22:47:25 得分 1

前些天不是有一个帖子介绍了基于   HTTP   的   QQ   协议吗,我按照这个写了一个   QQ   客户端,在   WSH   里啊,HTML   里啊都可以运行的。就因为只有一个线程头疼来着,Tencent   服务器现在太慢了,发一条消息会急死人的。  
   
  Emm...   先   Mark   ,再仔细看看~~Top

34 楼JK_10000(JK)回复于 2005-06-14 11:54:33 得分 10

iframe确实会相互堵塞:  
   
  test.html-----------  
  <iframe   src="a1.html"   >   </iframe>  
  <iframe   src="a1.html"   >   </iframe>  
   
  a1.html------------  
  <script   language=javascript   >  
  alert();  
  </script>  
   
  两个alert不能同时出现,证明不是真正的多线程  
   
   
  Top

35 楼JK_10000(JK)回复于 2005-06-14 12:04:40 得分 10

用showModelessDialog来模拟多线程的不足是:没法把这个对话框移出视线外。  
  开多个窗口,让多个窗口里的script各自执行,来模拟多线程应该可行。  
   
  下例是非模态alert,也应该算是模拟多线程的一种应用:  
  http://jkisjk.vip.sina.com/html/closeAlertBox.htmTop

36 楼JK_10000(JK)回复于 2005-06-14 12:06:58 得分 0

回复人:   a040liutao(冬之心)   (   )   信誉:100     2005-06-10   14:52:00     得分:   0      
   
  -----  
  可能是有时网络不好Top

37 楼BlueDestiny(Design Life - never-online.net)回复于 2005-06-14 14:24:35 得分 1

:)  
  做个记号。Top

38 楼emu_ston(祝福后山)回复于 2005-06-14 18:17:58 得分 0

jk:  
  showModelessDialog是我所知道的唯一能够堵塞正在运行的进程的方法,怎么可能用它来模拟多线程呢?你没有办法同时显示多个模式对话框,因为显示第一个的时候主页面的线程就停下来等了,一直到关掉它第二个才有可能打得开。  
  Top

39 楼emu_ston(祝福后山)回复于 2005-06-14 18:19:43 得分 0

哦看错了,我说的是modalDialog,你说的是showModelessDialog呵呵,全乱套了。Top

40 楼JK_10000(JK)回复于 2005-06-15 08:50:13 得分 10

http://jkisjk.vip.sina.com/html/closeAlertBox.htm  
   
  上面的非模态alert与自动关闭alert,  
  也应该算是模拟多线程的一种应用,可以同时弹出多个alert框  
  用的是showModelessDialog方式  
  因为当时看到有朋友发贴要求“自动关闭alert对话框”,  
  所以写了个来凑热闹,尽管没有实际用途。  
   
  ----捊须而笑  
  Top

41 楼emu_ston(祝福后山)回复于 2005-06-15 13:46:53 得分 0

还“捊须”呢,留胡子啦?Top

42 楼JK_10000(JK)回复于 2005-06-15 16:20:59 得分 0

一颏红须招风戏  
  两鬓斑发任月窥  
   
   
  岁月不饶人啊Top

43 楼emu_ston(祝福后山)回复于 2005-06-15 18:20:32 得分 0

还吟诗?要我送你刮胡子刀就明说嘛。Top

44 楼JK_10000(JK)回复于 2005-06-16 09:09:33 得分 0

年纪到,容易生感慨  
  附庸下风雅,辱没次期文,  
  聊以自娱,料无大妨  
   
  刮胡子刀就免了,  
  这些事让我儿我女婿送就得,  
  不敢劳stone大驾。  
   
  捊须而笑--Top

45 楼fason(咖啡人生)回复于 2005-06-16 20:59:41 得分 10

onreadystatechange函数来处理回调的时候更象多线程的效果些Top

46 楼emu_ston(祝福后山)回复于 2005-06-17 10:43:23 得分 0

不明白你的意思。你是说window.open之后在新窗口的onreadystatechange里面回掉主页面吗?Top

47 楼yonghengdizhen(等季节一过,繁花就凋落)回复于 2005-06-17 11:22:05 得分 0

我想fason就是这个意思.不过解释执行的脚本程序不管如何模拟,离多线程还远着呢.  
  onreadystatechange我也试过,其中一个onreadystatechange执行阻塞,其余onreadystatechange永远都没机会执行.  
  可以这么测试一下:  
  用两个iframe加载两个htm,其中一个iframe的onreadystatechange中使用模式对话框  
  你会发现,先加载完成的页面显示模式对话框,在未被确认之前,第二个页面永远没有机会加载完成.Top

48 楼yonghengdizhen(等季节一过,繁花就凋落)回复于 2005-06-17 11:30:52 得分 0

sorry,看来我说错了,ie6看起来不一样Top

49 楼yonghengdizhen(等季节一过,繁花就凋落)回复于 2005-06-17 11:44:11 得分 10

不过如下的测试页面可以说明问题:  
  x.htm         /*****直接在地址栏输入x.htm并回车,这时候你可能看不到两个alert同时出现的情况,并且在这种情况下,必须将该alert消息确认之后,两个文档才加载完成  
  <script>  
  function   test()  
  {  
  var   sDialogHW   =   "dialogWidth:350px;   dialogHeight:250px;status:no;";  
  var   sDialogULR   =   "about:blank";  
  retDlg=window.showModalDialog(sDialogULR,null,sDialogHW);  
  }  
  </script>  
  <iframe   onreadystatechange="test()"   src="y.htm"></iframe>  
  <iframe   onreadystatechange="test()"   src="z.htm"></iframe>  
  y.htm  
  <script>  
  alert(1)  
  </script>  
  <b>finish</b>  
  z.htm  
  <script>  
  alert(2)  
  </script>  
  <b>finish2</b>  
   
  Top

50 楼gu1dai(异域苍穹.百年飞行)回复于 2005-06-18 09:33:40 得分 1

挺好的Top

51 楼12345_(上山打老虎)回复于 2005-06-18 09:51:27 得分 1

咦!高手真xx多!:)Top

52 楼cuixiping(无心●愚公)回复于 2005-06-18 12:01:08 得分 10

这怎么多线程啊?  
  关键是   setInterval   ,定时的去执行一个命令而已。Top

53 楼superdullwolf(超级大笨狼,每天要自强,MVP)回复于 2005-06-19 08:59:52 得分 1

只有2个CPU以上才是真正的多线程。Top

54 楼patchclass(黑翼)回复于 2005-06-19 09:59:38 得分 10

showModelessDialog   用来实现alert()自动关闭的方法不错哦,呵呵  
  这个帖子还真蛮热闹的  
   
  对于用alert判断是否多线程不大科学吧,alert我想在浏览器端就是   执行阻塞的,什么时候见过同时一个页面出现两个alert的呢?  
  继续讨论Top

55 楼ops2000(吾痴石)回复于 2005-06-19 12:15:05 得分 10

我同意   fason(咖啡人生)   的onreadystatechange函数来处理回调的时候更象多线程的效果些。楼主作为对多线程的探讨,我没有任何异议。但不同的模式它的应用领域是不一样的,好比j2ee有j2ee的模式,j2se有自己的模式。我以为command模式就不应该是网页开发的合适模式。而最好能用onreadystatechange这种异步回调模式。模式直接影响框架设计,如果一个网页用command模式去思考,那么到后来越来越困难,网页也是越写越复杂。而如果一开始就能用异步回调模式来思考框架,可能很多问题迎刃而解,甚至都不会出现了。现在流行的ajax,我看了一些老外的核心代码都用的onreadystatechange。  
  个人浅见,仁仁智智Top

56 楼emu_ston(祝福后山)回复于 2005-06-20 08:59:41 得分 0

唉,还是吃的没文化的亏,看不明白啊。比如说我一开始的例子,用onreadystatechange怎么模拟呢?Top

57 楼emu_ston(祝福后山)回复于 2005-06-20 10:30:25 得分 0

今天看到fason的http://community.csdn.net/Expert/TopicView.asp?id=3191873被翻出来了。fason的方法来模拟相同的效果显然更简洁:  
   
  <html><head><title>emu   --   用command模式模拟多线程</title></head><body>  
  <SCRIPT   LANGUAGE="JavaScript">  
  <!--  
   
  var   _st   =   window.setTimeout;  
  window.setTimeout   =   function(fRef,   mDelay)   {  
  if(typeof   fRef   ==   'function'){  
  var   argu   =   Array.prototype.slice.call(arguments,2);  
  var   f   =   (function(){   fRef.apply(null,   argu);   });  
  return   _st(f,   mDelay);  
  }  
  return   _st(fRef,mDelay);  
  }  
   
  var   _int   =   window.setInterval;  
  window.setInterval   =   function(fRef,   mDelay)   {  
  if(typeof   fRef   ==   'function'){  
  var   argu   =   Array.prototype.slice.call(arguments,2);  
  var   f   =   (function(){   fRef.apply(null,   argu);   });  
  return   _int(f,   mDelay);  
  }  
  return   _st(fRef,mDelay);  
  }  
   
   
  function   startNewTask(){  
          var   target   =   document.getElementById("sampleResult").cloneNode(true);  
          with   (target){  
          id="";style.display="block";style.color=(Math.floor(Math.random()*   (1<<23)).toString(16)+"00000").substring(0,6);  
          }  
          document.body.insertBefore(target,document.body.lastChild);  
  var   parameter   =   {target:target,n:0,result:0}  
  parameter.timer   =   setInterval(count,1,parameter);  
  }  
   
  function     count(parameter){  
  with   (parameter){  
  if   (n<100){  
  if   (!target.stop)result   +=   ++n  
  target.innerHTML   =   result;  
  }else{  
  clearInterval(timer);  
  setTimeout(function(elm){document.body.removeChild(elm)},2000,target);  
  }  
  }  
  }  
   
  //-->  
  </SCRIPT>  
  <button   onclick="startNewTask()">开始新线程</button>  
   
  <BR><BR>  
  <div   id=sampleResult   onmouseover="this.stop=true"   onmouseout="this.stop=false"   style="display:none;cursor:hand">0</div>  
  </body>  
  </html>  
   
  有的时候command模式也许不是最好的办法,比如我上面的例子。写上面的例子纯粹只是为了演示command确实可以用在javascript中,并不表示我们任何时候都应该优先考虑这样做。  
   
  至于command模式本身,我仍认为它是最简洁优美的模式之一,在我们用各种语言解决问题的时候都可以考虑使用它,而不止于j2se。  
   
  套一句名言:如果你的工具箱里面只有榔头这一样工具,那么每个问题在你的眼里看起来都象钉子。Top

58 楼emu_ston(祝福后山)回复于 2005-06-20 10:34:20 得分 0

上面的代码在firefox下面闪烁太厉害,改一下:  
   
  function     count(parameter){  
  with   (parameter){  
  if   (n<1000){  
  if   (!target.stop){  
  result   +=   ++n;  
  target.innerHTML   =   result;  
  }  
  }else{  
  clearInterval(timer);  
  setTimeout(function(elm){document.body.removeChild(elm)},2000,target);  
  }  
  }  
  }  
   
  这种方式在firefox下面运行起来比在ie下面快,不大明白原因。Top

59 楼emu_ston(祝福后山)回复于 2005-06-20 10:52:03 得分 0

如果想要运算快一点,可以这样:  
   
  <html><head><title>emu   --   用fason的参数化定时器模拟多线程</title></head><body>  
  <SCRIPT   LANGUAGE="JavaScript">  
  <!--  
   
  var   _st   =   window.setTimeout;  
  window.setTimeout   =   function(fRef,   mDelay)   {  
  if(typeof   fRef   ==   'function'){  
  var   argu   =   Array.prototype.slice.call(arguments,2);  
  var   f   =   (function(){   fRef.apply(null,   argu);   });  
  return   _st(f,   mDelay);  
  }  
  return   _st(fRef,mDelay);  
  }  
   
  var   _int   =   window.setInterval;  
  window.setInterval   =   function(fRef,   mDelay)   {  
  if(typeof   fRef   ==   'function'){  
  var   argu   =   Array.prototype.slice.call(arguments,2);  
  var   f   =   (function(){   fRef.apply(null,   argu);   });  
  return   _int(f,   mDelay);  
  }  
  return   _st(fRef,mDelay);  
  }  
   
   
  function   startNewTask(){  
          var   target   =   document.getElementById("sampleResult").cloneNode(true);  
          with   (target){  
          id="";style.display="block";style.color=(Math.floor(Math.random()*   (1<<23)).toString(16)+"00000").substring(0,6);  
          }  
          document.body.insertBefore(target,document.body.lastChild);  
  var   parameter   =   {target:target,n:0,result:0}  
  parameter.timer   =   setInterval(count,1,parameter);  
  }  
   
  function     count(parameter){  
  with   (parameter){  
  if   (!target.stop){  
  for(var   i=0;i<speed;i++)  
  if   (n<MAX)   result   +=   ++n;  
  target.innerHTML   =   result;  
  }  
  if   (n>=MAX){  
  clearInterval(timer);  
  setTimeout(function(elm){document.body.removeChild(elm)},2000,target);  
  }  
  }  
  }  
   
  var   speed   =   1111;  
  var   MAX=100000;  
  //-->  
  </SCRIPT>  
  <button   onclick="startNewTask()">开始新线程</button>  
   
  <BR><BR>  
  <div   id=sampleResult   onmouseover="this.stop=true"   onmouseout="this.stop=false"   style="display:none;cursor:hand">0</div>  
  </body>  
  </html>  
   
  不过“线程”开多了或者加速太大了,就比较占cpu。Top

60 楼patchclass(黑翼)回复于 2005-06-20 11:34:56 得分 1

收藏,晚上回去   看看Top

61 楼zhiin(┈ Jcan ┈)回复于 2005-07-06 19:57:22 得分 0

 
   
   
                      强贴留名Top

62 楼wxylvmnn(城隍庙三当家的)回复于 2005-07-11 10:36:11 得分 0

某某路过此地。。。Top

63 楼777kit(型死)回复于 2005-07-21 15:48:34 得分 0

强贴留名  
  Top

64 楼mymmsc(热血老猫)回复于 2005-08-09 09:49:40 得分 0

太强了!Top

65 楼emu_ston(祝福后山)回复于 2005-08-11 14:09:04 得分 0

var   _int   =   window.setInterval;  
  window.setInterval   =   function(fRef,   mDelay)   {  
  if(typeof   fRef   ==   'function'){  
  var   argu   =   Array.prototype.slice.call(arguments,2);  
  var   f   =   (function(){   fRef.apply(null,   argu);   });  
  return   _int(f,   mDelay);  
  }  
  return   _st(fRef,mDelay);  
  }  
  应为:  
  var   _int   =   window.setInterval;  
  window.setInterval   =   function(fRef,   mDelay)   {  
  if(typeof   fRef   ==   'function'){  
  var   argu   =   Array.prototype.slice.call(arguments,2);  
  var   f   =   (function(){   fRef.apply(null,   argu);   });  
  return   _int(f,   mDelay);  
  }  
  return   _int(fRef,mDelay);  
  }Top

66 楼boyzhang(张郎)(爱你爱到Windows没BUG的那天)回复于 2005-08-21 17:48:19 得分 0

Mark一下!Top

67 楼hawk2004(漠沙飞-relearn)回复于 2005-08-30 14:20:29 得分 0

upTop

相关问题

  • 求教多线程模拟最高响应比算法!
  • 角色扮演或者身份模拟能否支持多线程?
  • [求助]请问在JavaScript中怎样实现多线程????
  • 请问在JavaScript中怎样实现多线程????
  • [求助]请问在JavaScript中怎样实现多线程????
  • 多线程啊多线程
  • 请问如何模拟下鱼的程序,具体算法,在vc里必须用多线程吗?
  • 多线程socket!!!
  • 多线程
  • 多线程

关键词

  • .net
  • j2ee
  • j2se

得分解答快速导航

  • 帖主:emu_ston
  • ttyp
  • cslren
  • fason
  • leojay1
  • DuJianDong
  • meizz
  • ttyp
  • ttyp
  • runmin
  • satans18
  • applebomb
  • ken2002
  • rightyeah
  • patchclass
  • s_phoenix
  • LGEN
  • dh20156
  • JK_10000
  • JK_10000
  • patchclass
  • a040liutao
  • HLis
  • JK_10000
  • JK_10000
  • BlueDestiny
  • JK_10000
  • fason
  • yonghengdizhen
  • gu1dai
  • 12345_
  • cuixiping
  • superdullwolf
  • patchclass
  • ops2000
  • patchclass

相关链接

  • Web开发类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo