今天和徐鵬程msn的時候聊起javascript不支持多線程。以前也看過有高手在wsh上可以創建thread對象,但是畢竟不是常規手段,我們做web應用一般沒有本地訪問權限的,用activex的沒試過,畢竟也不是javascript方式。
以前我們解決這樣的問題都是針對具體問題寫一段代碼來模擬多線程的,但是由于往往要對沒個線程單獨編碼,這樣的代碼十分冗長。學習設計模式的時候就曾經考慮過在javascript中實用command模式來更好的模擬多線程,但是一直沒有付諸實施,今天既然想起來了就試試看:
1
<html><head><title>emu -- 用command模式模擬多線程</title></head><body>
2
<SCRIPT LANGUAGE="JavaScript">
3
<!--
4
if (Array.prototype.shift==null)
5
Array.prototype.shift = function ()
{
6
var rs = this[0];
7
for (var i=1;i<this.length;i++) this[i-1]=this[i]
8
this.length=this.length-1
9
return rs;
10
}
11
if (Array.prototype.push==null)
12
Array.prototype.push = function ()
{
13
for (var i=0;i<arguments.length;i++) this[this.length]=arguments[i];
14
return this.length;
15
}
16
17
var commandList = [];
18
var nAction = 0;//控制每次運行多少個動作
19
var functionConstructor = function()
{}.constructor;
20
function executeCommands()
{
21
for (var i=0;i<nAction;i++)
22
if (commandList.length>0)
{
23
var command = commandList.shift();
24
if (command.constructor == functionConstructor)
25
if (command.scheduleTime == null || new Date()-command.scheduleTime>0)
26
command();
27
else
28
commandList.push(command);
29
}
30
}
31
32
function startNewTask()
{
33
var resultTemp = document.getElementById("sampleResult").cloneNode(true);
34
with (resultTemp)
{
35
id="";style.display="block";style.color=(Math.floor(Math.random()* (1<<23)).toString(16)+"00000").substring(0,6);
36
}
37
document.body.insertBefore(resultTemp,document.body.lastChild);
38
commandList.push(function()
{simThread(resultTemp,1);});
39
nAction++;
40
}
41
42
function simThread(temp,n)
{
43
if (temp.stop) n--;
44
else temp.innerHTML = temp.innerHTML - (-n);
45
if (n<1000)
46
commandList.push(function()
{simThread(temp,++n)});
47
else
{
48
var command = function()
{document.body.removeChild(temp);;nAction--;};
49
command.scheduleTime = new Date()-(-2000);
50
commandList.push(command);
51
}
52
}
53
54
window.onload = function()
{setInterval("executeCommands()",1);}
55
//-->
56
</SCRIPT>
57
<button onclick="startNewTask()">開始新線程</button>
58
59
<BR><BR>
60
<div id=sampleResult onmouseover="this.stop=true" onmouseout="this.stop=false" style="display:none;cursor:hand">0</div>
61
</body>
62
</html>

2



3

4

5



6

7

8

9

10

11

12



13

14

15

16

17

18

19



20



21

22



23

24

25

26

27

28

29

30

31

32



33

34



35

36

37

38



39

40

41

42



43

44

45

46



47



48



49

50

51

52

53

54



55

56

57

58

59

60

61

62

注意第26行。javascript里面函數也是對象,所以就沒有必要把函數調用包裝到do或者execute方法里面了,直接用()就可以讓函數對象運行起來:
command();
shift和push函數是javascript中array對象的函數,可是IE5居然沒有定義,最前面兩個函數是為IE5準備的。
在IE和FireFox下面通過 。