Раньше мы всегда говорили, что JS является однопоточным, а не многопоточным.Когда JS запускает на странице длительную задачу синхронизации, это приводит к зависанию страницы и влияет на взаимодействие с пользователем.Поэтому необходимо поставить задачу в очередь задач выполнить очередь задач Задачи не многопоточные, но теперь HTML5 дает нам возможность разрабатывать front-end -Web Workers API, давайте посмотрим, что такое Web Worker, как его использовать и как использовать его для вывода в реальном производстве.
Заинтересованные студенты могут добавить группу WeChat в конце статьи для совместного обсуждения~
1 Обзор
Веб-воркеры позволяют веб-приложению запускать операцию сценария в фоновом потоке, который отделяет основной поток выполнения. Преимущество этого заключается в том, что задача обработки может выполняться в отдельном потоке, что позволяет основному (обычно пользовательскому) потоку работать без блокировки.
Его функция заключается в создании многопоточной рабочей среды для JS, позволяющей основному потоку создавать рабочие потоки и назначать им задачи.Рабочие потоки также выполняются во время выполнения основного потока, не мешая друг другу. рабочие потоки запускаются, результаты возвращаются в основной поток. Преимущество этого заключается в том, что основной поток может передавать задачи с интенсивными вычислениями или задачами с высокой задержкой рабочим потокам, так что основной поток расслабляется, а не блокируется или замедляется. Это не означает, что сам язык JS поддерживает возможности многопоточности, но браузер как среда хоста обеспечивает многопоточную среду для запуска JS.
Тем не менее, поскольку после создания нового рабочего процесса он будет работать все время и не будет прерываться действиями основного потока, что способствует реагированию на общий поток основного потока в любое время, но также вызовет пустая трата ресурсов, поэтому его не следует использовать чрезмерно, и будьте осторожны, чтобы закрыть его, когда он израсходован. Другими словами: если у воркера нет ссылки на экземпляр, воркер будет закрыт сразу после бездействия; если ссылка на экземпляр воркера не равна 0, воркер не будет остановлен, если он простаивает.
взгляни на этосовместимость
Browser | IE | Edge | FireFox | Chrome | Safari |
---|---|---|---|---|---|
version | 10+ | 12+ | 3.5+ | 4+ | 4+ |
2. Используйте
2.1 Ограничения
Есть некоторые моменты, на которые следует обратить внимание при использовании рабочих потоков.
- ограничение гомологии Файл сценария, выполняемый рабочим потоком, должен иметь то же происхождение, что и файл сценария основного потока.Конечно, рабочему потоку нельзя разрешить читать файлы где-либо на других компьютерах.
- лимит файлов В целях безопасности рабочий поток не может читать локальные файлы, загружаемый им скрипт должен исходить из сети и иметь то же происхождение, что и скрипт основного потока.
- Ограничения на манипуляции с DOM
Рабочий поток выполняется в другом глобальном контексте, отличном от окна основного потока, в котором DOM-объект веб-страницы, на которой находится основной поток, не может быть ни прочитан, ни получен
document
,window
и т.п. объекты, но могут получитьnavigator
,location(只读)
,XMLHttpRequest
,setTimeout族
и другие API-интерфейсы браузера. - Ограничения на общение
Рабочий поток и основной поток находятся в разных контекстах и не могут взаимодействовать напрямую.
postMessage
способ общаться. - Ограничения скрипта
рабочий поток не может выполняться
alert
,confirm
, но вы можете использоватьXMLHttpRequest
Объект делает запрос ajax.
2.2 Примеры
Создать рабочие потоки в основном потоке очень просто:
var myWorker = new Worker(jsUrl, options)
Worker(), первым параметром является URL-адрес скрипта (должен соответствовать политике того же источника), этот параметр является обязательным, и могут быть загружены только JS-скрипты, иначе будет сообщено об ошибке. Второй параметр — это объект конфигурации, который является необязательным. Одной из его функций является указание имени рабочего процесса для различения нескольких рабочих потоков.
// 主线程
var myWorker = new Worker('worker.js', { name : 'myWorker' });
// Worker 线程
self.name // myWorker
Про апи что ли, наверное можно понять прямо из примера.Первый это js файл рабочего потока:
// workerThread1.js
let i = 1
function simpleCount() {
i++
self.postMessage(i)
setTimeout(simpleCount, 1000)
}
simpleCount()
self.onmessage = ev => {
postMessage(ev.data + ' 呵呵~')
}
В теле в файле HTML:
<!--主线程,HTML文件的body标签中-->
<div>
Worker 输出内容:<span id='app'></span>
<input type='text' title='' id='msg'>
<button onclick='sendMessage()'>发送</button>
<button onclick='stopWorker()'>stop!</button>
</div>
<script type='text/javascript'>
if (typeof(Worker) === 'undefined') // 使用Worker前检查一下浏览器是否支持
document.writeln(' Sorry! No Web Worker support.. ')
else {
window.w = new Worker('workerThread1.js')
window.w.onmessage = ev => {
document.getElementById('app').innerHTML = ev.data
}
window.w.onerror = err => {
w.terminate()
console.log(error.filename, error.lineno, error.message) // 发生错误的文件名、行号、错误内容
}
function sendMessage() {
const msg = document.getElementById('msg')
window.w.postMessage(msg.value)
}
function stopWorker() {
window.w.terminate()
}
}
</script>
Вы можете запустить его самостоятельно, чтобы увидеть эффект. Некоторые часто используемые API используются выше.
API в основном потоке,worker
Представляет экземпляр Worker:
-
worker.postMessage
: основной поток отправляет сообщение рабочему потоку, сообщение может быть любым типом данных, включая двоичные данные. -
worker.terminate
: основной поток закрывает рабочий поток -
worker.onmessage
: укажите обратный вызов, когда рабочий поток отправляет сообщение, или вы можете передатьworker.addEventListener('message',cb)
Путь -
worker.onerror
: Укажите обратный вызов при возникновении ошибки в рабочем потоке, или вы можетеworker.addEventListener('error',cb)
Глобальный объект в рабочем потокеself
, представляющий сам дочерний поток, затемthis
направлениеself
, на котором есть API:
-
self.postMessage
: рабочий поток отправляет сообщение в основной поток, сообщение может быть любым типом данных, включая двоичные данные. -
self.close
: рабочий поток закрывается -
self.onmessage
: укажите обратный вызов, когда основной поток отправляет сообщение рабочего потока, или вы можетеself.addEventListener('message',cb)
-
self.onerror
: Укажите обратный вызов при возникновении ошибки в рабочем потоке, или вы можетеself.addEventListener('error',cb)
Уведомление,w.postMessage(aMessage, transferList)
Метод принимает два параметра,aMessage
Возможна передача любого типа данных, включая объекты.Это взаимодействие является отношением копирования, то есть передачей значения, а не передачей адреса.Изменение работником содержимого сообщения не повлияет на основной поток. На самом деле рабочий механизм внутри браузера заключается в том, чтобы сначала сериализовать коммуникационный контент, а затем отправить сериализованную строку в Worker, который ее восстановит. необязательныйTransferableМассив объектов для передачи права собственности. Если право собственности на объект передается, он становится недоступным (прерванным) в контексте, в котором он был отправлен, и доступен только в рабочем потоке, которому он был отправлен. Переносимые объекты — это объекты-экземпляры, такие как ArrayBuffer, MessagePort или ImageBitmap,transferList
Вы не можете передать null в массиве.
Более подробный API см.MDN - WorkerGlobalScope.
API для загрузки скрипта в рабочий поток:
importScripts('script1.js') // 加载单个脚本
importScripts('script1.js', 'script2.js') // 加载多个脚本
3. Реальные боевые сценарии
Лично я считаю, что Web Worker можно использовать как калькулятор, когда он нам нужен, мы можем его вынуть и нажать, и мы должны убрать его, когда он не используется~
-
зашифрованные данные Некоторые алгоритмы шифрования и дешифрования более сложны, или при шифровании и дешифровании большого количества данных они потребляют много вычислительных ресурсов и приводят к тому, что поток пользовательского интерфейса перестает отвечать на запросы, поэтому сейчас самое время использовать Web Worker. потоки могут сделать пользователей более бесшовными.
-
Предварительная выборка данных Иногда для повышения скорости загрузки данных можно использовать рабочий поток для получения данных заранее, потому что рабочий поток можно использовать для
XMLHttpRequest
из. -
предварительный рендеринг В некоторых случаях рендеринга сцены, таких как рендеринг холста, требуется сложный расчет, когда возникает эффект таких отражений, преломлений, света и других материалов, логика может использовать эти вычисления для выполнения рабочих потоков, может использоваться множество рабочих потоков, существует аПример трассировки лучей.
-
Сложные сценарии обработки данных Некоторый поиск, сортировка, фильтрация и анализ потребуют очень много времени, в этом случае Web Worker можно использовать для этого, не занимая основной поток.
-
Предварительная загрузка изображений Иногда на странице много изображений или когда есть несколько больших изображений, если бизнес-ограничения не предусматривают отложенную загрузку, вы также можете использовать Web Worker для загрузки изображений, вы можете обратиться кИзучение этой статьи, вот краткое содержание.
// 主线程 let w = new Worker("js/workers.js"); w.onmessage = function (event) { var img = document.createElement("img"); img.src = window.URL.createObjectURL(event.data); document.querySelector('#result').appendChild(img) } // worker线程 let arr = [...好多图片路径]; for (let i = 0, len = arr.length; i < len; i++) { let req = new XMLHttpRequest(); req.open('GET', arr[i], true); req.responseType = "blob"; req.setRequestHeader("client_type", "DESKTOP_WEB"); req.onreadystatechange = () => { if (req.readyState == 4) { postMessage(req.response); } } req.send(null); }
Будьте осторожны в бою
- Хотя использование рабочего потока не будет занимать основной поток, запуск рабочего потока потребует больше ресурсов.
- XMLHttpRequest используется в основном потоке, в процессе запроса браузер открывает другой поток асинхронного http-запроса, но ресурсы основного потока по-прежнему потребляются в процессе взаимодействия.
Чтобы использовать Web Worker в проекте Webpack, см.:Как использовать Web Worker под ES6+Webpack
Что касается Shared Worker, Service Worker и т.д., то читать не будем, IE не нравится
Большинство сообщений в Интернете имеют разную глубину и даже некоторые несоответствия. Следующие статьи являются кратким изложением процесса обучения. Если вы найдете какие-либо ошибки, пожалуйста, оставьте сообщение, чтобы указать ~
Ссылаться на:
PS: Всех приглашаю обратить внимание на мой публичный аккаунт [Front End Afternoon Tea], давайте работать вместе~
Кроме того, вы можете присоединиться к группе WeChat «Front-end Afternoon Tea Exchange Group», нажмите и удерживайте, чтобы определить QR-код ниже, чтобы добавить меня в друзья, обратите вниманиеДобавить группу, я заберу тебя в группу~