Я читал о веб-работниках в HTML5, но я знаю, что JavaScript является однопоточным.
Мой вопрос:
Как работают веб-сотрудники, выполняющие многопоточную работу? или как они имитируют это, если это не верно многопоточное? Мне кажется неясным здесь.
Я читал о веб-работниках в HTML5, но я знаю, что JavaScript является однопоточным.
Мой вопрос:
Как работают веб-сотрудники, выполняющие многопоточную работу? или как они имитируют это, если это не верно многопоточное? Мне кажется неясным здесь.
Как уже отмечалось в нескольких комментариях, Workers действительно многопоточны.
Некоторые моменты, которые могут помочь прояснить ваше мышление:
Вы создаете файл .js как "рабочий", и он запускает процессы в отдельном потоке. Вы можете передавать данные JSON между ними и "основной" нитью. Однако у рабочих нет доступа к некоторым вещам, таким как DOM.
Итак, если, скажем, вы хотели решить сложные математические проблемы, вы могли бы позволить пользователю вводить вещи в браузер, передавать эти переменные работнику, позволять ему выполнять вычисления в фоновом режиме, а в основном потоке, который вы разрешаете пользователь делает другие вещи или показывает индикатор выполнения или что-то еще, а затем, когда рабочий закончил, он передает ответ, и вы печатаете его на странице. Вы можете выполнить несколько задач асинхронно и вернуть ответы не по порядку по мере их завершения. Довольно аккуратно!
Немного поздно, но я просто задал себе тот же вопрос, и я придумал следующий ответ:
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
в конце.
В браузерах запрос ajax может порождать новый поток для его фактической выборки данных, но его внутренняя работа выходит за рамки JavaScript API (что браузер позволяет вам контролировать с точки зрения инструкций JavaScript). Что касается разработчика, результат запроса newtwork обрабатывается основным потоком.
Это достигается с помощью циклов событий, а не многопоточности. Это справедливо для нескольких браузеров и, очевидно, для Node.js. Ниже приведены некоторые ссылки, в некоторых случаях немного устаревшие, но я предполагаю, что основная идея все еще сохраняется в наши дни.
Этот факт является причиной того, что JavaScript называется Event-driven, но не многопоточным.
Что касается WebWorkers, это API-интерфейсы JavaScript, которые предоставляют разработчику контроль над многопоточным процессом.
Таким образом, они обеспечивают способ считывания и записи значений, и это делается среди прочих следующими способами:
thisWorker.onmessage = function(e) {console.log('Message ' + e.data + ' received from worker');}
). Должно быть, это должно быть с помощью обычной Event Loop.SharedArrayBuffer
, с которой безопасно доступны потоки, используя функции Atomic
. Я обнаружил, что это ясно показано в этой статье: JavaScript: от рабочих до общей памятиБраузер запускает поток с помощью javascript, который вы хотите выполнить. Итак, это настоящая нить с этой работой веб-мастеров, ваш js больше не однопоточный.