惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
D
Darknet – Hacking Tools, Hacker News & Cyber Security
P
Privacy International News Feed
NISL@THU
NISL@THU
Know Your Adversary
Know Your Adversary
G
GRAHAM CLULEY
The Hacker News
The Hacker News
P
Privacy & Cybersecurity Law Blog
S
Schneier on Security
T
Troy Hunt's Blog
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
S
Security Affairs
WordPress大学
WordPress大学
T
Tailwind CSS Blog
博客园 - Franky
T
The Exploit Database - CXSecurity.com
雷峰网
雷峰网
S
SegmentFault 最新的问题
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
S
Securelist
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
有赞技术团队
有赞技术团队
爱范儿
爱范儿
Help Net Security
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 三生石上(FineUI控件)
C
CERT Recently Published Vulnerability Notes
C
Cisco Blogs
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
Spread Privacy
Spread Privacy
Last Week in AI
Last Week in AI
S
Security @ Cisco Blogs
博客园 - 司徒正美
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
罗磊的独立博客
博客园 - 叶小钗
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
J
Java Code Geeks
T
Threatpost
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位

博客园 - 让心灵去旅行

项目小结 sql语句性能提高 oracle的异常 简单的消息发送小程序 XP风格进度条 随机抽取不重复的数据 xmlhttp实现无刷新页面 VS.Net 2005中文版下载地址收藏 在线统计与跟踪(新) 简单ocx控件制作方法(原创) 自己做控件小例子 可以双击的DataGrid 权限管理的方案(只有实现思想) 收藏几段SQL Server语句和存储过程(转载) 动态添加和删除行 键盘各键对应的键值 只能输入数值的输入框 操作动态表格的控件 模仿QQ的菜单滚动效果
在Javascript中用command模式模拟多线程,包含注释
让心灵去旅行 · 2006-12-25 · via 博客园 - 让心灵去旅行

    Javascript本身是不支持多线程的,直到在网上看到这样一篇文章, javascript中用command模式模拟多线程中 ,觉得非常好,用command模式,巧妙的模拟了多线程.虽是模拟,但很实用.对于javascript不熟的人,可能很难去理解,因此添加了注释,重新发布出来。希望能给需要的人一点帮助。

<html>
    
<head>
        
<title>用command模式模拟多线程</title>
    
</head>
    
<body>
    
<script language="JavaScript" type="text/javascript">
    
<!--
     
//objectName.prototype:返回Array对象类型原型的引用
     //命令出队列,返回第一个元素
     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 ()
    
{
    
//arguments原本为Array中的队列的标志
        for (var i=0;i<arguments.length;i++this[this.length]=arguments[i];
        
return this.length;
    }


    
//为一个ArrayList对象,其属性shift将返回队列中的第一个元素,即一个函数对象.
    var commandList = [];

    
//控制每次运行多少个动作
    var nAction = 0;

    
//object.constructor表示创建对象的函数
    var functionConstructor = function(){}.constructor;
    

    
//用于增加线程。克隆一个div对象,添加到页面,并且进站simThread命令
    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); //否则数据+n
    }

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

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

    }


    window.onload 
= function()
    
{
    setInterval(
"executeCommands()",1);//每隔1秒,执行函数executeCommands()
    }
    

    
//让多个函数可以一起执行的方法。
    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();            
//执行函数simThread
                    else
                        commandList.push(command);    
//增加一个线程
            }

    }

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

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