Помимо Gears, сейчас ничего не доступно, но есть много разговоров о том, как это реализовать, поэтому я думаю, посмотрите на этот вопрос, поскольку ответ, без сомнения, изменится в будущем.
Вот соответствующая документация для Gears: WorkerPool API
WHATWG предлагает черновой вариант рекомендации для рабочих потоков: веб-работники
В Chrome встроены Gears, поэтому он может создавать потоки, хотя для этого требуется подтверждение от пользователя (и он использует другой API для веб-работников, хотя он будет работать в любом браузере с установленным плагином Gears):
Демонстрация Google Gears WorkerPool (не очень хороший пример, поскольку он работает слишком быстро для тестирования в Chrome и Firefox, хотя IE запускает его достаточно медленно, чтобы блокировать взаимодействие)
IE8 и IE9 могут создавать потоки только с установленным плагином Gears
Хотя Safari 4 поддерживает веб-работников, похоже, что только Firefox поддерживает передачу сложных объектов через postMessage: hacks.mozilla.org/2009/07/working-smarter-not-harder См. Последний абзац этого поста об использовании в реальном мире в проекте Bespin для ссылок на шим, который реализует Worker API в терминах Google Gears и который добавляет недостающие функции в рабочую реализацию Safari 4, а также подробности того, как они реализовали прозрачные настраиваемые события поверх интерфейса postMessage.
Сэм Хаслер
6
Теперь IE9 вышел, вы можете обновить «IE8 может создавать потоки только с установленным плагином Gears» до «IE8 и IE9 может
создавать
2
@ inf3rno для длительных вычислений в другом потоке, чтобы они не замедляли работу браузера.
Сэм Хаслер
6
@ SamHasler Вы можете пересмотреть свой ответ. Веб-работники теперь поддерживаются всеми современными настольными браузерами. См. Также caniuse.com/#search=worker
Роб W
2
@ SamHasler также стоит отметить, что Google Gears больше не поддерживается.
skeggse
73
Другой способ сделать многопоточность и асинхронность в JavaScript
До HTML5 JavaScript допускал выполнение только одного потока на страницу.
Был некоторый Hacky способ имитации асинхронного исполнения с Выход , setTimeout(), setInterval(), XMLHttpRequestили обработчики событий (см в конце этого поста для примера с выходом и setTimeout()).
Но с HTML5 теперь мы можем использовать рабочие потоки для распараллеливания выполнения функций. Вот пример использования.
Реальная многопоточность
Многопоточность: рабочие потоки JavaScript
HTML5 представил веб-рабочие потоки (см .: совместимость браузеров )
Примечание. 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/2576706function getScriptPath(foo){return window.URL.createObjectURL(newBlob([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 1var worker1 =newWorker(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 2var worker2 =newWorker(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 3var worker3 =newWorker(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);
Мы видим, что три потока выполняются в параллельном режиме и печатают их текущее значение на странице. Они не замораживают страницу, потому что они выполняются в фоновом режиме с разделенными потоками.
Многопоточность: с несколькими фреймами
Другим способом достижения этого является использование нескольких фреймов , каждый из которых будет выполнять поток. Мы можем дать iframe некоторые параметры по URL, и iframe может связаться со своим родителем, чтобы получить результат и распечатать его обратно ( iframe должен находиться в том же домене).
Этот пример работает не во всех браузерах! iframes обычно работают в том же потоке / процессе, что и главная страница (но Firefox и Chromium, кажется, обрабатывают это по-разному).
Поскольку фрагмент кода не поддерживает несколько файлов HTML, я просто предоставлю здесь разные коды:
index.html:
//The 3 iframes containing the code (take the thread id in param)<iframe id="threadFrame1" src="thread.html?id=1"></iframe><iframe id="threadFrame2" src="thread.html?id=2"></iframe><iframe id="threadFrame3" src="thread.html?id=3"></iframe>//Divs that shows the result<div id="result1"></div><div id="result2"></div><div id="result3"></div><script>//This function is called by each iframefunction threadResult(threadId, result){
document.getElementById("result"+ threadId).innerHTML = result;}</script>
thread.html:
//Get the parameters in the URL: http://stackoverflow.com/a/1099670/2576706function getQueryParams(paramName){var qs = document.location.search.split('+').join(' ');var params ={}, tokens, re =/[?&]?([^=]+)=([^&]*)/g;while(tokens = re.exec(qs)){
params[decodeURIComponent(tokens[1])]= decodeURIComponent(tokens[2]);}return params[paramName];}//The thread code (get the id from the URL, we can pass other parameters as needed)var MAX_VALUE =100000;(function thread(){var threadId = getQueryParams('id');for(var i=0; i<MAX_VALUE; i++){
parent.threadResult(threadId, i);}})();
Имитация многопоточности
Однопоточный: эмулируйте параллелизм JavaScript с помощью setTimeout ()
«Наивным» способом было бы выполнение функции setTimeout()одна за другой, например так:
setTimeout(function(){/* Some tasks */},0);
setTimeout(function(){/* Some tasks */},0);[...]
Но этот метод не работает, потому что каждая задача будет выполняться одна за другой.
Мы можем симулировать асинхронное выполнение, вызывая функцию рекурсивно так:
Как вы можете видеть, этот второй метод очень медленный и замораживает браузер, потому что он использует основной поток для выполнения функций.
Однопоточный: эмулирует параллелизм JavaScript с yield
Выход - это новая функция в ECMAScript 6 , она работает только на самой старой версии Firefox и Chrome (в Chrome необходимо включить экспериментальный JavaScript, появляющийся в chrome: // flags / # enable-javascript-harmony ).
Ключевое слово yield приводит к приостановке выполнения функции генератора, и значение выражения, следующего за ключевым словом yield, возвращается вызывающей стороне генератора. Его можно рассматривать как генераторную версию ключевого слова return.
Генератор позволяет приостановить выполнение функции и возобновить ее позже. Генератор может быть использован для планирования ваших функций с техникой, называемой прыжками на батуте .
Там нет истинного потока в JavaScript. JavaScript, будучи гибким языком, действительно позволяет вам эмулировать некоторые из них. Вот пример, с которым я столкнулся на днях.
Вот только способ симулировать многопоточность в Javascript
Теперь я собираюсь создать 3 потока, которые будут вычислять сложение чисел, числа можно разделить на 13, а числа можно разделить на 3 до 10000000000. И эти 3 функции не могут работать одновременно с тем, что означает параллелизм. Но я покажу вам трюк, который заставит эти функции работать рекурсивно в одно и то же время: jsFiddle
Этот код принадлежит мне.
Часть тела
<div class="div1"><input type="button" value="start/stop" onclick="_thread1.control ? _thread1.stop() : _thread1.start();"/><span>Counting summation of numbers till 10000000000</span> = <span id="1">0</span></div><div class="div2"><input type="button" value="start/stop" onclick="_thread2.control ? _thread2.stop() : _thread2.start();"/><span>Counting numbers can be divided with13 till 10000000000</span> = <span id="2">0</span></div><div class="div3"><input type="button" value="start/stop" onclick="_thread3.control ? _thread3.stop() : _thread3.start();"/><span>Counting numbers can be divided with3 till 10000000000</span> = <span id="3">0</span></div>
Часть 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 runif(this.control){// checking for control to runif(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 , компилятор, который преобразует ваш код в конечный автомат, эффективно позволяя вам эмулировать потоки. Это делается путем добавления оператора «выдачи» (обозначается как «->») к языку, который позволяет писать асинхронный код в одном линейном блоке кода.
В необработанном Javascript лучшее, что вы можете сделать, это использовать несколько асинхронных вызовов (xmlhttprequest), но это не очень многопоточность и очень ограничено. Google Gears добавляет в браузер ряд API, некоторые из которых можно использовать для поддержки многопоточности.
Если вы не можете или не хотите использовать какой-либо материал AJAX, используйте iframe или десять! ;) У вас могут быть процессы, запущенные в iframes параллельно с главной страницей, не беспокоясь о проблемах, сравнимых с кроссбраузерными или синтаксическими проблемами с точечной сетью AJAX и т. Д., И вы можете вызывать JavaScript главной страницы (включая импортированный ею JavaScript) из IFrame.
Например, в родительском iframe вызывать egFunction()родительский документ после загрузки содержимого iframe (это асинхронная часть)
parent.egFunction();
Динамически генерируйте iframes, так что основной HTML-код свободен от них, если хотите.
Это описание было слишком кратким, на мой взгляд. Не могли бы вы уточнить, как сделать эту технику, или опубликовать ссылку на учебник, показывающий некоторый код?
oligofren
3
Другой возможный метод - использование интерпретатора javascript в среде javascript.
Создав несколько интерпретаторов и управляя их выполнением из основного потока, вы можете имитировать многопоточность с каждым потоком, работающим в его собственной среде.
Подход несколько похож на веб-работников, но вы предоставляете переводчику доступ к глобальной среде браузера.
У Javascript нет потоков, но у нас есть работники.
Рабочие могут быть хорошим выбором, если вам не нужны общие объекты.
Большинство реализаций браузера фактически распределяют работников по всем ядрам, что позволяет вам использовать все ядра. Вы можете увидеть демо этого здесь .
Я разработал библиотеку под названием task.js, которая делает это очень простым.
task.js Упрощенный интерфейс для запуска кода, интенсивно использующего процессор, для всех ядер (node.js и web)
Примером будет
function blocking (exampleArgument){// block thread}// turn blocking pure function into a worker taskconst blockingAsync = task.wrap(blocking);// run task on a autoscaling worker pool
blockingAsync('exampleArgumentValue').then(result =>{// do something with result});
Со спецификацией HTML5 вам не нужно писать слишком много JS для того же самого или находить некоторые хаки.
Одна из функций, представленных в HTML5, - это Web Workers - это JavaScript, работающий в фоновом режиме, независимо от других скриптов, не влияющий на производительность страницы.
Ответы:
См. Http://caniuse.com/#search=worker для получения самой последней информации о поддержке.
Следующим было состояние поддержки около 2009 года.
Слова, которые вы хотите найти в Google, являются рабочими потоками JavaScript
Помимо Gears, сейчас ничего не доступно, но есть много разговоров о том, как это реализовать, поэтому я думаю, посмотрите на этот вопрос, поскольку ответ, без сомнения, изменится в будущем.
Вот соответствующая документация для Gears: WorkerPool API
WHATWG предлагает черновой вариант рекомендации для рабочих потоков: веб-работники
И есть также рабочие потоки DOM Mozilla
Обновление: июнь 2009 г., текущее состояние поддержки браузером потоков JavaScript
Firefox 3.5 имеет веб-работников. Несколько демонстраций веб-работников, если вы хотите увидеть их в действии:
Плагин Gears также можно установить в Firefox.
Safari 4 и ночные нити WebKit имеют рабочие потоки:
В Chrome встроены Gears, поэтому он может создавать потоки, хотя для этого требуется подтверждение от пользователя (и он использует другой API для веб-работников, хотя он будет работать в любом браузере с установленным плагином Gears):
IE8 и IE9 могут создавать потоки только с установленным плагином Gears
источник
Другой способ сделать многопоточность и асинхронность в JavaScript
До HTML5 JavaScript допускал выполнение только одного потока на страницу.
Был некоторый Hacky способ имитации асинхронного исполнения с Выход ,
setTimeout()
,setInterval()
,XMLHttpRequest
или обработчики событий (см в конце этого поста для примера с выходом иsetTimeout()
).Но с HTML5 теперь мы можем использовать рабочие потоки для распараллеливания выполнения функций. Вот пример использования.
Реальная многопоточность
Многопоточность: рабочие потоки JavaScript
HTML5 представил веб-рабочие потоки (см .: совместимость браузеров )
Примечание. IE9 и более ранние версии не поддерживают его.
Эти рабочие потоки являются потоками JavaScript, которые работают в фоновом режиме, не влияя на производительность страницы. Для получения дополнительной информации о Web Worker прочитайте документацию или этот учебник .
Вот простой пример с 3-мя потоками Web Worker, которые считаются до MAX_VALUE и показывают текущее вычисленное значение на нашей странице:
Мы видим, что три потока выполняются в параллельном режиме и печатают их текущее значение на странице. Они не замораживают страницу, потому что они выполняются в фоновом режиме с разделенными потоками.
Многопоточность: с несколькими фреймами
Другим способом достижения этого является использование нескольких фреймов , каждый из которых будет выполнять поток. Мы можем дать iframe некоторые параметры по URL, и iframe может связаться со своим родителем, чтобы получить результат и распечатать его обратно ( iframe должен находиться в том же домене).
Этот пример работает не во всех браузерах! iframes обычно работают в том же потоке / процессе, что и главная страница (но Firefox и Chromium, кажется, обрабатывают это по-разному).
Поскольку фрагмент кода не поддерживает несколько файлов HTML, я просто предоставлю здесь разные коды:
index.html:
thread.html:
Имитация многопоточности
Однопоточный: эмулируйте параллелизм JavaScript с помощью setTimeout ()
«Наивным» способом было бы выполнение функции
setTimeout()
одна за другой, например так:Но этот метод не работает, потому что каждая задача будет выполняться одна за другой.
Мы можем симулировать асинхронное выполнение, вызывая функцию рекурсивно так:
Как вы можете видеть, этот второй метод очень медленный и замораживает браузер, потому что он использует основной поток для выполнения функций.
Однопоточный: эмулирует параллелизм JavaScript с yield
Выход - это новая функция в ECMAScript 6 , она работает только на самой старой версии Firefox и Chrome (в Chrome необходимо включить экспериментальный JavaScript, появляющийся в chrome: // flags / # enable-javascript-harmony ).
Генератор позволяет приостановить выполнение функции и возобновить ее позже. Генератор может быть использован для планирования ваших функций с техникой, называемой прыжками на батуте .
Вот пример:
источник
С HTML5 "side-specs" больше не нужно взламывать javascript с помощью setTimeout (), setInterval () и т. Д.
HTML5 & Friends представляет спецификацию веб-работников javascript . Это API для асинхронного и независимого запуска скриптов.
Ссылки на спецификацию и учебник .
источник
Там нет истинного потока в JavaScript. JavaScript, будучи гибким языком, действительно позволяет вам эмулировать некоторые из них. Вот пример, с которым я столкнулся на днях.
источник
В Javascript нет настоящей многопоточности, но вы можете получить асинхронное поведение, используя
setTimeout()
и асинхронные запросы AJAX.Что именно вы пытаетесь достичь?
источник
Вот только способ симулировать многопоточность в Javascript
Теперь я собираюсь создать 3 потока, которые будут вычислять сложение чисел, числа можно разделить на 13, а числа можно разделить на 3 до 10000000000. И эти 3 функции не могут работать одновременно с тем, что означает параллелизм. Но я покажу вам трюк, который заставит эти функции работать рекурсивно в одно и то же время: jsFiddle
Этот код принадлежит мне.
Часть тела
Часть Javascript
Я надеюсь, что этот путь будет полезным.
источник
Вы можете использовать Narrative JavaScript , компилятор, который преобразует ваш код в конечный автомат, эффективно позволяя вам эмулировать потоки. Это делается путем добавления оператора «выдачи» (обозначается как «->») к языку, который позволяет писать асинхронный код в одном линейном блоке кода.
источник
Новый движок v8, который должен выйти сегодня, поддерживает его (я думаю)
источник
В необработанном Javascript лучшее, что вы можете сделать, это использовать несколько асинхронных вызовов (xmlhttprequest), но это не очень многопоточность и очень ограничено. Google Gears добавляет в браузер ряд API, некоторые из которых можно использовать для поддержки многопоточности.
источник
Если вы не можете или не хотите использовать какой-либо материал AJAX, используйте iframe или десять! ;) У вас могут быть процессы, запущенные в iframes параллельно с главной страницей, не беспокоясь о проблемах, сравнимых с кроссбраузерными или синтаксическими проблемами с точечной сетью AJAX и т. Д., И вы можете вызывать JavaScript главной страницы (включая импортированный ею JavaScript) из IFrame.
Например, в родительском iframe вызывать
egFunction()
родительский документ после загрузки содержимого iframe (это асинхронная часть)Динамически генерируйте iframes, так что основной HTML-код свободен от них, если хотите.
источник
Другой возможный метод - использование интерпретатора javascript в среде javascript.
Создав несколько интерпретаторов и управляя их выполнением из основного потока, вы можете имитировать многопоточность с каждым потоком, работающим в его собственной среде.
Подход несколько похож на веб-работников, но вы предоставляете переводчику доступ к глобальной среде браузера.
Я сделал небольшой проект, чтобы продемонстрировать это .
Более подробное объяснение в этом посте .
источник
У Javascript нет потоков, но у нас есть работники.
Рабочие могут быть хорошим выбором, если вам не нужны общие объекты.
Большинство реализаций браузера фактически распределяют работников по всем ядрам, что позволяет вам использовать все ядра. Вы можете увидеть демо этого здесь .
Я разработал библиотеку под названием task.js, которая делает это очень простым.
Примером будет
источник
Со спецификацией HTML5 вам не нужно писать слишком много JS для того же самого или находить некоторые хаки.
Одна из функций, представленных в HTML5, - это Web Workers - это JavaScript, работающий в фоновом режиме, независимо от других скриптов, не влияющий на производительность страницы.
Поддерживается практически во всех браузерах:
Chrome - 4.0+
IE - 10.0+
Мозилла - 3.5+
Сафари - 4.0+
Опера - 11,5+
источник