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

推荐订阅源

S
Secure Thoughts
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tenable Blog
Project Zero
Project Zero
T
The Exploit Database - CXSecurity.com
T
Threat Research - Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cyberwarzone
Cyberwarzone
PCI Perspectives
PCI Perspectives
G
GRAHAM CLULEY
H
Hacker News: Front Page
Cloudbric
Cloudbric
Latest news
Latest news
N
News and Events Feed by Topic
C
CERT Recently Published Vulnerability Notes
Attack and Defense Labs
Attack and Defense Labs
SecWiki News
SecWiki News
Security Latest
Security Latest
MyScale Blog
MyScale Blog
阮一峰的网络日志
阮一峰的网络日志
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
V2EX - 技术
V2EX - 技术
B
Blog RSS Feed
L
LINUX DO - 最新话题
人人都是产品经理
人人都是产品经理
Last Week in AI
Last Week in AI
IT之家
IT之家
Jina AI
Jina AI
Y
Y Combinator Blog
博客园 - 聂微东
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Visual Studio Blog
P
Privacy International News Feed
B
Blog
S
Schneier on Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
Help Net Security
Help Net Security
D
DataBreaches.Net
博客园_首页
G
Google Developers Blog
I
InfoQ
量子位
大猫的无限游戏
大猫的无限游戏
S
Security @ Cisco Blogs

博客园 - 让心灵去旅行

项目小结 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]
       }