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

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 让心灵去旅行

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