有没有办法在JavaScript中进行多线程?
有关最新的支持信息,请访问http://caniuse.com/#search=worker.
以下是大约2009年的支持状况.
你想谷歌的词是JavaScript工作者线程
除了Gears之外,目前还没有什么可用,但是有很多关于如何实现这一点的讨论,所以我想看看这个问题,因为答案无疑会在未来发生变化.
以下是Gears:WorkerPool API的相关文档
WHATWG有一份关于工作者线程的建议草案:Web Workers
还有Mozilla的DOM Worker Threads
更新: 2009年6月,当前浏览器支持JavaScript线程的状态
Firefox 3.5有网络工作者.一些网络工作者的演示,如果你想看到他们的行动:
模拟退火("试一试"链接)
太空入侵者(帖子末尾的链接)
MoonBat JavaScript Benchmark(第一个链接)
Gears插件也可以安装在Firefox中.
Safari 4和WebKit nightlies都有工作线程:
JavaScript Ray Tracer
Chrome有Gears,所以它可以做线程,虽然它需要用户的确认提示(它使用不同的API到Web工作者,虽然它可以在安装了Gears插件的任何浏览器中工作):
谷歌Gears WorkerPool演示(不是一个很好的例子,因为它运行速度太快,无法在Chrome和Firefox中进行测试,尽管IE运行得足够慢以至于阻止了交互)
IE8和IE9只能安装Gears插件的线程
在HTML5之前,JavaScript只允许每页执行一个线程.
有以模拟与异步执行一些哈克的方式产率,setTimeout()
,setInterval()
,XMLHttpRequest
或事件处理程序(看到此信息的用于与例如端部收率和setTimeout()
).
但是使用HTML5,我们现在可以使用工作线程来并行执行函数.这是一个使用示例.
HTML5引入了Web Worker Threads(请参阅:浏览器兼容性)
注意:IE9及更早版本不支持它.
这些工作线程是在后台运行的JavaScript线程,不会影响页面的性能.有关Web Worker的 更多信息,请阅读文档或本教程.
下面是一个简单的示例,其中3个Web Worker线程计数到MAX_VALUE并在页面中显示当前计算的值:
//As a worker normally take another JavaScript file to execute we convert the function in an URL: http://stackoverflow.com/a/16799132/2576706
function getScriptPath(foo){ return window.URL.createObjectURL(new Blob([foo.toString().match(/^\s*function\s*\(\s*\)\s*\{(([\s\S](?!\}$))*[\s\S])/)[1]],{type:'text/javascript'})); }
var MAX_VALUE = 10000;
/*
* Here are the workers
*/
//Worker 1
var worker1 = new Worker(getScriptPath(function(){
self.addEventListener('message', function(e) {
var value = 0;
while(value <= e.data){
self.postMessage(value);
value++;
}
}, false);
}));
//We add a listener to the worker to get the response and show it in the page
worker1.addEventListener('message', function(e) {
document.getElementById("result1").innerHTML = e.data;
}, false);
//Worker 2
var worker2 = new Worker(getScriptPath(function(){
self.addEventListener('message', function(e) {
var value = 0;
while(value <= e.data){
self.postMessage(value);
value++;
}
}, false);
}));
worker2.addEventListener('message', function(e) {
document.getElementById("result2").innerHTML = e.data;
}, false);
//Worker 3
var worker3 = new Worker(getScriptPath(function(){
self.addEventListener('message', function(e) {
var value = 0;
while(value <= e.data){
self.postMessage(value);
value++;
}
}, false);
}));
worker3.addEventListener('message', function(e) {
document.getElementById("result3").innerHTML = e.data;
}, false);
// Start and send data to our worker.
worker1.postMessage(MAX_VALUE);
worker2.postMessage(MAX_VALUE);
worker3.postMessage(MAX_VALUE);
使用HTML5"side-specs" 不再需要使用setTimeout(),setInterval()等来破解javascript.
HTML5和Friends介绍了javascript Web Workers规范.它是一个异步和独立运行脚本的API.
指向规范和教程的链接.
JavaScript中没有真正的线程.JavaScript是可塑的语言,它允许你模仿它的一部分.这是我前几天遇到的一个例子.
Javascript中没有真正的多线程,但您可以使用setTimeout()
异步AJAX请求获得异步行为.
你到底想要完成什么?
这里只是一种在Javascript中模拟多线程的方法
现在我将创建3个线程,它们将计算数字加法,数字可以除以13,数字可以除以3到10000000000.这三个函数不能像Concurrency那样同时运行.但是我将向您展示一个技巧,使这些函数在同一时间递归运行:jsFiddle
这段代码属于我.
身体的一部分
Counting summation of numbers till 10000000000 = 0Counting numbers can be divided with 13 till 10000000000 = 0Counting numbers can be divided with 3 till 10000000000 = 0
Javascript部分
var _thread1 = {//This is my thread as object control: false,//this is my control that will be used for start stop value: 0, //stores my result current: 0, //stores current number func: function () { //this is my func that will run if (this.control) { // checking for control to run if (this.current < 10000000000) { this.value += this.current; document.getElementById("1").innerHTML = this.value; this.current++; } } setTimeout(function () { // And here is the trick! setTimeout is a king that will help us simulate threading in javascript _thread1.func(); //You cannot use this.func() just try to call with your object name }, 0); }, start: function () { this.control = true; //start function }, stop: function () { this.control = false; //stop function }, init: function () { setTimeout(function () { _thread1.func(); // the first call of our thread }, 0) } }; var _thread2 = { control: false, value: 0, current: 0, func: function () { if (this.control) { if (this.current % 13 == 0) { this.value++; } this.current++; document.getElementById("2").innerHTML = this.value; } setTimeout(function () { _thread2.func(); }, 0); }, start: function () { this.control = true; }, stop: function () { this.control = false; }, init: function () { setTimeout(function () { _thread2.func(); }, 0) } }; var _thread3 = { control: false, value: 0, current: 0, func: function () { if (this.control) { if (this.current % 3 == 0) { this.value++; } this.current++; document.getElementById("3").innerHTML = this.value; } setTimeout(function () { _thread3.func(); }, 0); }, start: function () { this.control = true; }, stop: function () { this.control = false; }, init: function () { setTimeout(function () { _thread3.func(); }, 0) } }; _thread1.init(); _thread2.init(); _thread3.init();
我希望这种方式会有所帮助.
您可以使用Narrative JavaScript,一种将您的代码转换为状态机的编译器,有效地允许您模拟线程.它通过在允许您在单个线性代码块中编写异步代码的语言添加"让步"运算符(标记为" - >")来实现.