Це навмисне дизайнерське рішення чи проблема з нашими браузерами, які сьогодні є виправленими у наступних версіях?
Це навмисне дизайнерське рішення чи проблема з нашими браузерами, які сьогодні є виправленими у наступних версіях?
Відповіді:
JavaScript не підтримує багатопотокові передачі, оскільки інтерпретатор JavaScript у браузері є єдиним потоком (AFAIK). Навіть Google Chrome не дозволить одночасно запускати JavaScript однієї веб-сторінки, оскільки це може спричинити великі проблеми з одночасністю існуючих веб-сторінок. Усі Chrome - це окремі декілька компонентів (різні вкладки, плагіни та ін.) В окремі процеси, але я не можу уявити, щоб одна сторінка мала більше ніж один потік JavaScript.
Однак ви можете використовувати, як було запропоновано, setTimeout
щоб дозволити якесь планування та "фальшиву" паралельність. Це призводить до того, що браузер відновить контроль над потоком візуалізації та запустить код JavaScript, наданий setTimeout
після заданої кількості мілісекунд. Це дуже корисно, якщо ви хочете дозволити оглядовому огляду (побаченому) оновитись під час виконання операцій над ним. Якщо просто переглядати координати, наприклад, координати та відповідно оновлювати елемент, ви просто зможете побачити початкову та кінцеву позиції, і нічого між ними.
Ми використовуємо бібліотеку абстракцій у JavaScript, яка дозволяє нам створювати процеси та потоки, якими керує той самий інтерпретатор JavaScript. Це дозволяє нам виконувати дії таким чином:
Це дозволяє певну форму планування і підробляє паралелізм, запуск і зупинку ниток, тощо, але це не буде справжньою багаторізкою. Я не думаю, що він коли-небудь буде реалізований у самій мові, оскільки справжня багатопотокова передача корисна лише в тому випадку, коли браузер може запускати одну сторінку з багатопотоковими потоками (або навіть більше одного ядра), а труднощі є набагато більшими ніж додаткові можливості.
Для майбутнього JavaScript перевірте це: https://developer.mozilla.org/presentations/xtech2006/javascript/
Тут є багатопотокова програма JavaScript (з деякими обмеженнями). Google впровадив працівників для Gears, а працівників включають до HTML5. Більшість браузерів вже додали підтримку цієї функції.
Безпека ниток даних гарантована, оскільки всі дані, що передаються працівнику / від них, серіалізуються / копіюються.
Для отримання додаткової інформації читайте:
Традиційно JS призначався для коротких, швидкодіючих фрагментів коду. Якщо у вас йшли великі розрахунки, ви робили це на сервері - ідея програми JS + HTML , яка тривалий час працювала у вашому браузері, роблячи нетривіальні речі, була абсурдною.
Звичайно, зараз у нас це є. Але браузерам знадобиться трохи наздогнати - більшість з них розроблені навколо однопотокової моделі, і змінити це непросто. Google Gears виконує багато можливих проблем, вимагаючи, щоб фонове виконання було ізольованим - не змінюючи DOM (оскільки це не є безпечним для потоків), немає доступу до об'єктів, створених головним потоком (ditto). Незважаючи на обмеження, це, швидше за все, буде найбільш практичним дизайном на найближче майбутнє, як тому, що спрощує дизайн браузера, так і тому, що це зменшує ризик дозволити недосвідченим кодерам JS заплутатися з нитками ...
@marcio :
Чому це причина не застосовувати багатопотоковість у Javascript? Програмісти можуть робити все, що завгодно, за допомогою інструментів, які вони мають.
Тож давайте не дамо їм інструментів, які так легко не зловживати, що кожен інший відкритий веб-сайт закінчується збоєм мого браузера. Наївна реалізація цього привела б вас прямо на територію, яка викликала в MS стільки головних болів під час розробки IE7: автори додатків грали швидко і вільно з нарізною моделлю, в результаті чого приховані помилки, які стали очевидними при зміні життєвих циклів об'єктів на первинному потоці . БАД. Якщо ви пишете багатопотокові додатки ActiveX для IE, я думаю, що це стосується території; не означає, що потрібно йти далі від цього.
Я не знаю обґрунтування цього рішення, але я знаю, що ви можете змоделювати деякі переваги багатопотокового програмування за допомогою setTimeout. Можна створити ілюзію того, що багато процесів роблять речі одночасно, хоча насправді все відбувається однією ниткою.
Просто попросіть свою функцію трохи попрацювати, а потім зателефонуйте на зразок:
setTimeout(function () {
... do the rest of the work...
}, 0);
І будь-які інші речі, які потрібно робити (наприклад, оновлення інтерфейсу користувача, анімовані зображення тощо), трапляться, коли вони отримають можливість.
loop
всередині, setTimeout
але, мабуть, це не працює. Ви робили щось подібне чи у вас хакер? прикладом може бути масив з 1000 елемента, я очікую використання двох для циклів всередині двох setTimeout
викликів, таким чином, що перший цикл проходить через і друкує елемент 0..499
, другий цикл проходить через і елемент друку 500..999
.
Ви маєте на увазі, чому мова не підтримує багатопотоковість чи чому двигуни JavaScript у браузерах не підтримують багатопотоковість?
Відповідь на перше запитання полягає в тому, що JavaScript в браузері призначений для роботи в пісочниці та машинно / не залежно від ОС, додавання підтримки для багатопотокових передач ускладнить мову та прив'язує мову занадто тісно до ОС.
Node.js 10.5+ підтримує робочі потоки як експериментальну функцію (ви можете використовувати її з включеним прапором --experimental-worker ): https://nodejs.org/api/worker_threads.html
Отже, правило таке:
Робочі нитки призначені для довгоживучих ниток, тобто ви створюєте фонову нитку, а потім спілкуєтесь з нею за допомогою передачі повідомлення.
В іншому випадку, якщо вам потрібно виконати велике завантаження процесора з анонімною функцією, ви можете перейти до https://github.com/wilk/microjob , крихітної бібліотеки, побудованої навколо робочих ниток.
Як вже говорив matt b, питання не дуже зрозуміле. Якщо припустити, що ви запитуєте про підтримку багатопотокової мови мовою: адже вона не потрібна для 99,999% застосованих у браузері додатків. Якщо вам це справді потрібно, є обхідні шляхи (наприклад, за допомогою window.setTimeout).
Взагалі, багатопотоковість - це дуже, дуже, дуже, дуже, дуже, дуже важко (я сказав, що це важко?) Отримати правильне рішення, якщо ви не встановите додаткові обмеження (наприклад, використовуючи лише незмінні дані).
Intel проводила кілька досліджень з відкритим кодом з багатопотокової роботи в Javascript, її недавно було показано на GDC 2012. Ось посилання на відео . Дослідницька група використовувала OpenCL, який в основному зосереджується на наборах чіпів Intel та ОС Windows. Проект має кодову назву RiverTrail і код доступний на GitHub
Ще кілька корисних посилань:
В даний час деякі браузери підтримують багатопотоковість. Отже, якщо вам потрібно, ви можете використовувати певні бібліотеки. Наприклад, перегляньте наступні матеріали:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (підтримка фонових потоків);
https://keithwhor.github.io/multithread.js/ (бібліотека).
Це реалізація, яка не підтримує багатопотоковість. В даний час Google Gears пропонує спосіб використовувати певну форму одночасності, виконуючи зовнішні процеси, але це стосується цього.
Новий браузер Google повинен випустити сьогодні (Google Chrome) паралельно виконує деякий код, відокремлюючи його.
Основна мова, звичайно, може мати таку ж підтримку, як, скажімо, Java, але підтримка чогось на зразок одночасності Ерланга ніде не знаходиться біля горизонту.
Javascript - це однопоточна мова. Це означає, що він має один стек викликів та одну купу пам'яті. Як очікувалося, він виконує код для того, щоб завершити виконання фрагмента коду, перш ніж перейти до наступного. Це синхронно, але часом може бути шкідливим. Наприклад, якщо функція потребує деякого часу, щоб виконати або доводиться щось чекати, вона тим часом заморожує все.
Без належної підтримки мови для синхронізації потоків навіть нові сенси не мають сенсу намагатися. Існуючі складні програми JS (наприклад, що-небудь, що використовує ExtJS), швидше за все, несподівано вийдуть з ладу, але без synchronized
ключового слова чи чогось подібного також було б дуже важко або навіть неможливо написати нові програми, які ведуть себе правильно.
Однак ви можете скористатися функцією eval, щоб принести одночасність ДУМУ ДОСЛІДНОМ
/* content of the threads to be run */
var threads = [
[
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');"
],
[
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');"
]
];
window.onload = function() {
var lines = 0, quantum = 3, max = 0;
/* get the longer thread length */
for(var i=0; i<threads.length; i++) {
if(max < threads[i].length) {
max = threads[i].length;
}
}
/* execute them */
while(lines < max) {
for(var i=0; i<threads.length; i++) {
for(var j = lines; j < threads[i].length && j < (lines + quantum); j++) {
eval(threads[i][j]);
}
}
lines += quantum;
}
}
Багатопотокова передача за допомогою javascript очевидно можлива за допомогою веб-роботників, принесених HTML5.
Основна відмінність веб-роботників від стандартного багатопотокового середовища полягає в тому, що ресурси пам’яті не поділяються на основний потік, посилання на об’єкт не видно з одного потоку в інший. Нитки спілкуються за допомогою обміну повідомленнями, тому можливо реалізувати алгоритм виклику синхронізації та паралельного виклику, керуючись подією дизайнерської схеми.
Існує багато фреймворків, що дозволяють структурувати програмування між потоками, серед них OODK-JS, OOP js-рамка, що підтримує одночасне програмування https://github.com/GOMServices/oodk-js-oop-for-js