在Javascript中用command模式模拟多线程,包含注释

本文介绍了一种使用JavaScript中的command模式来模拟多线程的方法。通过构造特定的命令队列和利用JavaScript的单线程特性,实现了类似多线程的效果。文章提供了具体的实现代码和详细解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    Javascript本身是不支持多线程的,直到在网上看到这样一篇文章,  javascript中用command模式模拟多线程中 ,觉得非常好,用command模式,巧妙的模拟了多线程.虽是模拟,但很实用.对于javascript不熟的人,可能很难去理解,因此添加了注释,重新发布出来。希望能给需要的人一点帮助。
  
None.gif < html >
None.gif    
< head >
None.gif        
< title > 用command模式模拟多线程 </ title >
None.gif    
</ head >
None.gif    
< body >
None.gif    
< script language = " JavaScript "  type = " text/javascript " >
None.gif    
<!--
None.gif     
// objectName.prototype:返回Array对象类型原型的引用
None.gif
      // 命令出队列,返回第一个元素
None.gif
      if  (Array.prototype.shift == null )
None.gif     Array.prototype.shift 
=   function  ()
ExpandedBlockStart.gifContractedBlock.gif     
dot.gif {
InBlock.gif         
var rs = this[0];
InBlock.gif         
for (var i=1;i<this.length;i++this[i-1]=this[i];
InBlock.gif         
this.length=this.length-1;
InBlock.gif         
return rs;
ExpandedBlockEnd.gif     }

None.gif
None.gif    
// 命令进队列,返回长度
None.gif
     if  (Array.prototype.push == null )
None.gif    Array.prototype.push 
=   function  ()
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif    
//arguments原本为Array中的队列的标志
InBlock.gif
        for (var i=0;i<arguments.length;i++this[this.length]=arguments[i];
InBlock.gif        
return this.length;
ExpandedBlockEnd.gif    }

None.gif
None.gif    
// 为一个ArrayList对象,其属性shift将返回队列中的第一个元素,即一个函数对象.
None.gif
     var  commandList  =  [];
None.gif
None.gif    
// 控制每次运行多少个动作
None.gif
     var  nAction  =   0 ;
None.gif
None.gif    
// object.constructor表示创建对象的函数
ExpandedBlockStart.gifContractedBlock.gif
     var  functionConstructor  =   function () dot.gif {} .constructor;
None.gif    
None.gif
None.gif    
// 用于增加线程。克隆一个div对象,添加到页面,并且进站simThread命令
None.gif
     function  startNewTask()
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
var resultTemp = document.getElementById("sampleResult").cloneNode(true);
InBlock.gif        
with (resultTemp)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        id
="";
InBlock.gif        
//背景不显示
InBlock.gif
        style.display="block";
InBlock.gif        
//背景色随机
InBlock.gif
        style.color=(Math.floor(Math.random()* (1<<23)).toString(16)+"00000").substring(0,6);
ExpandedSubBlockEnd.gif        }

InBlock.gif    
//增加页面元素
InBlock.gif
        document.body.insertBefore(resultTemp,document.body.lastChild);
InBlock.gif
InBlock.gif    
//增加一个模拟线程的函数
ExpandedSubBlockStart.gifContractedSubBlock.gif
        commandList.push(function()dot.gif{simThread(resultTemp,1);});
InBlock.gif
InBlock.gif    
//增加一个线程后,线程总数增加
InBlock.gif
        nAction++;
ExpandedBlockEnd.gif    }

None.gif
None.gif    
// 模拟线程
None.gif
     function   simThread(temp,n)
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
if(temp.stop)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        n
--;//鼠标悬停时,数据保持不动,但是鼠标恢复的时候再保持原值
ExpandedSubBlockEnd.gif
    }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        temp.innerHTML 
= temp.innerHTML - (-n); //否则数据+n
ExpandedSubBlockEnd.gif
    }

InBlock.gif        
if (n<1000)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
//每次执行的时候都会将CommandList中第一个元素拿出来执行.因此队列中将减少一个.
InBlock.gif
        //在n<1000,即还没有加到500500的时候,需要将正在执行的线程,以及n的值加1后添加到队列的末尾
InBlock.gif
        //执行到下一个循环的时候再执行
ExpandedSubBlockStart.gifContractedSubBlock.gif
            commandList.push(function()dot.gif{simThread(temp,++n)});
ExpandedSubBlockEnd.gif    }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
//当已经执行到500500的值,即n=1000后,需要将线程注销
InBlock.gif
            var command = function()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif        
//从页面移除线程
InBlock.gif
        document.body.removeChild(temp);
InBlock.gif        nAction
--;
ExpandedSubBlockEnd.gif        }
;
InBlock.gif            command.scheduleTime 
= new Date()-(-2000);
InBlock.gif        
//从Arraylist中注销模拟显示的线程
InBlock.gif
            commandList.push(command);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

None.gif
None.gif    window.onload 
=   function ()
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif    setInterval(
"executeCommands()",1);//每隔1秒,执行函数executeCommands()
ExpandedBlockEnd.gif
    }
    
None.gif
None.gif    
// 让多个函数可以一起执行的方法。
None.gif
     function  executeCommands()
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
for (var i=0;i<nAction;i++)
InBlock.gif            
if (commandList.length>0)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif                
var command = commandList.shift();//取得数组中第一个函数对象
InBlock.gif

InBlock.gif                
if (command.constructor == functionConstructor)
InBlock.gif                    
if (command.scheduleTime == null || new Date()-command.scheduleTime>0)
InBlock.gif                        command();            
//执行函数simThread
InBlock.gif
                    else
InBlock.gif                        commandList.push(command);    
//增加一个线程
ExpandedSubBlockEnd.gif
            }

ExpandedBlockEnd.gif    }

None.gif    
// -->
None.gif
     </ script >
None.gif    
< button onclick = " startNewTask() " > 开始新线程 </ button >
None.gif    
< br />
None.gif    
< div id = " sampleResult "  onmouseover = " this.stop=true "  onmouseout = " this.stop=false "  style = " display:none;cursor:hand " > 0 </ div >
None.gif
</ body >
None.gif
</ html >

上面值得说明的是几个对象:
一, CommandList为一个ArrayList对象,可以通过ArrayList.shift()取出第一个元素,可通过ArrayList.push()将元素放进去.其ArrayList中保存的对象为Command.
二,Command对象为一个函数如下,可以直接执行.
  function (){simThread(resultTemp,n);}其中n是可以传递的变量
三,command.constructor即FunctionConstructor
    function Function()
      {
          [native code]
       }


转载于:https://www.cnblogs.com/applegreen/archive/2006/12/25/602679.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值