Четох за уеб работници в HTML5, но знам, че JavaScript е еднонишков.
Въпросът ми е:
Как тогава уеб работниците извършват многопоточна работа? или как го симулират, ако не е наистина многонишков? Тук не ми изглежда ясно.
Четох за уеб работници в HTML5, но знам, че JavaScript е еднонишков.
Въпросът ми е:
Как тогава уеб работниците извършват многопоточна работа? или как го симулират, ако не е наистина многонишков? Тук не ми изглежда ясно.
Както няколко коментара вече посочиха, Workers наистина са многонишкови.
Някои точки, които могат да ви помогнат да изясните мислите си:
Малко късно, но току-що си зададох същия въпрос и стигнах до следния отговор:
Javascript в браузърите винаги е еднопоточен и основно последствие е, че „едновременният“ достъп към променливи (основното главоболие на многонишковото програмиране) всъщност не е едновременно; това е вярно с изключение на уебработниците, които всъщност се изпълняват в отделни нишки и едновременният достъп до променливи трябва да се третира по малко ясен начин.
Аз не съм JavaScript нинджа, но аз също бях убеден, че JavaScript в браузъра се предоставя като процес с една нишка, без да обръщам много внимание на това дали е вярно или на обосновката зад това убеждение.
Прост факт, който подкрепя това предположението е, че когато програмирате в JavaScript, не трябва да се интересувате от паралелен достъп до споделени променливи. Всеки разработчик, без дори да мисли за проблема, пише код, сякаш всеки достъп до променлива е последователен.
С други думи, не е нужно да се притеснявате за така наречения Модел на памет.
Всъщност няма нужда да разглеждате WebWorkers, за да включите паралелна обработка в JavaScript. Помислете за (асинхронна) AJAX заявка. И помислете колко небрежно бихте се справили с едновременния достъп до променливи:
var counter = 0;
function asyncAddCounter() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
counter++;
}
};
xhttp.open("GET", "/a/remote/resource", true);
xhttp.send();
}
asyncAddCounter();
counter++;
Каква е стойността на counter
в края на процеса? Това е 2
. Няма значение, че се чете и пише „едновременно“, никога няма да доведе до 1
. Това означава, че достъпът до counter
винаги е последователен. Ако две нишки наистина имат достъп до стойността едновременно, и двете могат да започнат с четене на 0
и двете да напишат 1
накрая.
В браузърите действителното извличане на данни от отдалечен ресурс е скрито за разработчика и вътрешната му работа е извън обхвата на API на JavaScript (това, което браузърът ви позволява да контролирате по отношение на инструкциите на JavaScript). Що се отнася до програмиста, резултатът от мрежовата заявка се обработва от основната нишка.
Накратко, действителното изпълнение на заявката не е видимо, но извикването на обратното извикване (обработване на резултата чрез персонализиран JavaScript код) се изпълнява от главната нишка.
Вероятно, ако не беше за уебработниците, терминът „многопоточност“ никога няма да влезе в света на Javascript.
Изпълнението на заявката и асинхронното извикване на обратното извикване всъщност се постига чрез използване на цикли на събития, а не многопоточност. Това е вярно за няколко браузъра и очевидно за Node.js. Следват някои препратки, в някои случаи малко остарели, но предполагам, че основната идея се запазва и днес.
Този факт е причината, поради която се казва, че JavaScript е управляван от събития, но не и многонишков.< br> Забележете, че по този начин JavaScript позволява асинхронни идиоми, но не и паралелно изпълнение на JavaScript код (извън уебработници). Терминът асинхронен просто обозначава факта, че резултатът от две инструкции може да бъде обработен в разбъркан ред.
Що се отнася до WebWorkers, те са API на JavaScript, които дават на разработчиците контрол над многонишков процес.
Като такива те предоставят изрични начини за обработка на едновременен достъп до споделена памет (четене и запис на стойности в различни нишки ), и това се прави, между другото, по следните начини:
thisWorker.onmessage = function(e) {console.log('Message ' + e.data + ' received from worker');}
). Предполагам, че трябва да е чрез обичайния цикъл на събитията.SharedArrayBuffer
, която е достъпна за безопасен поток чрез функциите Atomic
. Намерих това ясно изложено в тази статия: JavaScript: От работници към споделена паметСъздавате .js файл като "работник" и той изпълнява процеси в отделна нишка. Можете да предавате JSON данни напред и назад между него и "главната" нишка. Работниците обаче нямат достъп до определени неща като DOM.
Така че, ако, да речем, искате да решите сложни математически задачи, можете да позволите на потребителя да въвежда неща в браузъра, да прехвърли тези променливи на работника, да го оставите да направи изчисленията във фонов режим, докато в главната нишка оставяте потребителя да направи други неща, или да покаже лента за напредъка или нещо подобно, и след това, когато воркърът свърши, той връща отговора обратно и вие го отпечатвате на страницата. Можете дори да решите множество задачи асинхронно и да върнете обратно отговорите в нередовен ред, когато завършат. Доста спретнат!
Браузърът стартира нишка с javascript, който искате да изпълните. Така че това е истинска нишка, с това нещо за уеб работници вашият js вече не е еднопоточен.
Всъщност основното объркване, мисля тук, идва от това, че хората намират хитри начини да правят нещата едновременно. Ако се замислите, JavaScript очевидно не е многонишков и въпреки това имаме начини да правим нещата паралелно, така че какво се случва?
Задаването на правилния въпрос е това, което ще доведе до отговора тук. Кой отговаря за нишките? Има един отговор по-горе, който казва, че JS е просто език, а не модел на нишки. Напълно вярно! JavaScript няма нищо общо с това. Отговорността пада върху V8. Вижте тази връзка за повече информация -› https://v8.dev/ Така че V8 позволява една нишка на JS Контекст, което означава, че колкото и да се опитвате, създаването на нова тема е просто невъзможно. И все пак хората създават така наречените работници и ние се объркваме. За да ми отговорите, ви питам следното. Възможно ли е да стартирате 2 V8 и двата да интерпретират някакъв JS код? Точно решението на нашия проблем. Работниците комуникират със съобщения, защото техният контекст е различен. Те са други неща, които не знаят нищо за нашия контекст, следователно се нуждаят от информация, която идва под формата на съобщение.