Web Worker — это многопоточное решение Javascript, предоставляемое HTML5. Мы можем передать веб-работнику некоторый вычислительно интенсивный код для запуска без зависания пользовательского интерфейса.
1: Как использовать WorkerОсновной принцип Web Worker заключается в использовании класса Worker для загрузки файла JavaScript в текущий основной поток JavaScript для открытия нового потока, который имеет эффект неблокирующего выполнения и предоставляет интерфейс для обмена данными между основным потоком. и новая тема: postMessage, onmessage.
Итак, как его использовать, давайте посмотрим на примере:
//worker.jsonmessage =function (evt){ var d = evt.data;//Получить отправленные данные через evt.data postMessage(d);//Отправить полученные данные в основной поток}HTML-страница: test.html.
<!DOCTYPE HTML><html><head> <meta http-equiv=Content-Type content=text/html; charset=utf-8/> <script type=text/javascript>//Основной поток веб-страницы var worker = new Worker(worker.js); //Создаем объект Worker и передаем ему URL-адрес скрипта, который будет выполнен в новом потоке worker.postMessage(hello world); //Отправляем данные работнику worker.onmessage; =function(evt){ //Получаем функцию данных console.log(evt.data) от работника; //Выводим данные, отправленные от исполнителя} </script> </head> <body></body>< / html>После открытия файла test.html в браузере Chrome консоль выводит hello world, что указывает на успешное выполнение программы.
Из этого примера мы видим, что использование веб-воркеров в основном разделено на следующие части:
Основная тема WEB:
1. Загрузите файл JS через worker = new Worker(url), чтобы создать работника и вернуть экземпляр работника.
2. Отправьте данные работнику через метод worker.postMessage(data).
3. Привяжите метод worker.onmessage для получения данных, отправленных воркером.
4. Вы можете использовать worker.terminate() для прекращения выполнения работника.
новый рабочий поток:
1. Отправьте данные в основной поток с помощью метода postMessage(data).
2. Привяжите метод onmessage для получения данных, отправленных основным потоком.
2: Что может сделать Worker?Теперь, когда мы знаем, как использовать Web Worker, для чего он нужен и какие проблемы он может нам помочь решить. Давайте посмотрим на пример последовательности Фибоначчи.
Как мы все знаем, в математике последовательность Фибоначчи определяется рекурсивно: F0=0, F1=1, Fn=F(n-1)+F(n-2) (n>=2, nεN*), Общая реализация javascript:
var fibonacci =function(n) { return n <2? n : аргументы.callee(n -1) + аргументы.callee(n -2);};//fibonacci(36)Время выполнения с помощью этого метода для вычисления последовательности Фибоначчи 39 в Chrome составляет 19097 миллисекунд, но когда дело доходит до вычисления 40, браузер напрямую сообщает, что скрипт занят.
Поскольку JavaScript выполняется в одном потоке, браузер не может выполнять другие сценарии JavaScript в процессе расчета последовательности, а поток рендеринга пользовательского интерфейса также будет приостановлен, что приведет к переходу браузера в состояние зомби. Использование веб-воркера для помещения процесса вычисления последовательности в новый поток позволит избежать этой ситуации. См. конкретные примеры:
//fibonacci.jsvar fibonacci =function(n) { return n <2? n : аргументы.callee(n -1) + аргументы.callee(n -2);};onmessage =function(event) { var n = parseInt (event.data, 10); postMessage(fibonacci(n));};HTML-страница: fibonacci.html.
<!DOCTYPE HTML><html><head><meta http-equiv=Content-Type content=text/html; charset=utf-8/><title>веб-рабочий фибоначчи</title><script type=text/javascript > onload = function() { var worker =new Worker('fibonacci.js'); worker.addEventListener('message', function(event) { var timer2 = (new Date()).valueOf(); console.log( 'Result:'+event.data, 'Time:'+ timer2, 'Затраченное время:'+ (timer2 - timer) }, false); (new Date()).valueOf(); console.log('Начать расчет: 40', 'Время:' + setTimeout(function(){); console.log('Функция таймера была выполнена при вычислении последовательности', 'Time:'+ (new Date()).valueOf() },1000); worker.postMessage(40); Я выполнил ', 'time:'+ (new Date()).valueOf() } </script></head><body></body></html> при вычислении последовательности;Откройте файл fibonacci.html в Chrome, и консоль получит следующий вывод:
Начать отсчет: 40. Время: 1316508212705.
Когда я рассчитал последовательность, я выполнил время: 1316508212734
Функция таймера, выполняемая при расчете последовательности: 1316508213735
Результат: 102334155 Время: 1316508262820 Прошедшее время: 50115
Этот пример показывает, что вычисление последовательности Фибоначчи, выполняемое в рабочем потоке, не влияет на выполнение кода основного потока. Он полностью вычисляется в собственном независимом потоке, и результаты отправляются обратно в основной поток только после завершения расчета. завершенный.
Используя веб-воркеры, мы можем выполнять некоторые сложные и масштабные операции на веб-интерфейсе, не влияя на отображение страницы, и при этом отвратительное сообщение о занятости скрипта не появится.
В следующем примере веб-воркер используется для расчета пикселей в сцене. Когда сцена открывается, она рисуется один за другим. Работник вычисляет только одно значение пикселя.
Третье: Другие попытки WorkerМы уже знаем, что Worker создает работника, получая URL-адрес, поэтому можем ли мы использовать веб-воркеров для выполнения некоторых запросов, аналогичных jsonp? Как мы все знаем, jsonp загружает данные json, вставляя теги сценария, а элемент сценария загружает и выполняет весь процесс блокируется. Было бы здорово, если бы веб-работники могли использоваться для реализации асинхронной загрузки.
В следующем примере данные JSON размером 169,42 КБ будут загружены тремя различными методами: веб-рабочий, jsonp и ajax.
// /aj/webWorker/core.jsfunction $E(id) { return document.getElementById(id);}onload =function() { //Загрузка через веб-воркер $E('workerLoad').onclick =function() { var url = 'http://js.wcdn.cn/aj/mblog/face2' var d = (new Date()).valueOf(); var worker = new; Worker(url); worker.onmessage =function(obj) { console.log('web worker: '+ ((new Date()).valueOf() - d) }; E('jsonpLoad').onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face1'; var d = (новый) Date()).valueOf(); STK.core.io.scriptLoader({ метод:'post', url: url, onComplete: function() { console.log('jsonp: '+ ((new Date()) .valueOf() - d)); } }); //Загрузка $E('ajaxLoad') через ajax.onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face'; var d = (new Date()).valueOf(); STK.core.io.ajax({url: url, onComplete: function( json) { console.log('ajax: '+ ((new Date()).valueOf() - d));HTML-страница:/aj/webWorker/worker.html
<!DOCTYPE HTML><html><head><meta http-equiv=Content-Type content=text/html; charset=utf-8/><title>Пример рабочего процесса: загрузить данные</title><script src=http; ://js.t.sinajs.cn/STK/js/gaea.1.14.js type=text/javascript></script><script type=text/javascript src=http://js.wcdn.cn/aj/webWorker/core.js></script></head><body> <тип ввода=кнопка id=workerLoad значение=загрузка веб-воркера></input> < тип ввода=кнопка id=jsonpLoad value=jsonp load></input> <тип ввода=button id=ajaxLoad value=ajax load></input></body></html>
Настроить ХОСТ
127.0.0.1 js.wcdn.cn
Получите доступ к странице через http://js.wcdn.cn/aj/webWorker/worker.html, а затем загрузите данные тремя способами, чтобы получить вывод на консоль:
веб-работник: 174jsonp: 25ajax: 38
Попробовав несколько раз, я обнаружил, что разница во времени между загрузкой данных через jsonp и ajax не сильно отличается, а время загрузки веб-воркера всегда находится на высоком уровне, поэтому использование веб-воркера для загрузки данных по-прежнему происходит относительно медленно, даже в случае большого объема данных преимущества нет, возможно, Workerу потребуется время для инициализации новых потоков. Нет никаких преимуществ, кроме отсутствия блокировки во время загрузки.
Итак, может ли веб-воркер поддерживать междоменную загрузку js? На этот раз мы получаем доступ к странице через http://127.0.0.1/aj/webWorker/worker.html. При нажатии кнопки загрузки веб-воркера в Chrome ничего не отображается. появится следующее сообщение об ошибке. Отсюда мы можем знать, что веб-воркер не поддерживает междоменную загрузку JS, что является плохой новостью для веб-сайтов, которые развертывают статические файлы на отдельном статическом сервере.
Поэтому веб-воркеры можно использовать только для загрузки json-данных в том же домене, а ajax уже умеет это делать, и это более эффективно и универсально. Пусть Рабочий делает то, что у него хорошо получается.
Четвертое: РезюмеВеб-работники выглядят великолепно, но они дьявольские.
Что мы можем сделать:
1. Вы можете загрузить JS для выполнения большого количества сложных вычислений без зависания основного процесса и общаться через postMessage, onmessage
2. Вы можете загрузить дополнительные файлы скриптов в воркер через importScripts(url)
3. Вы можете использовать setTimeout(),clearTimeout(),setInterval() иclearInterval().
4. Вы можете использовать XMLHttpRequest для отправки запросов.
5. Доступен доступ к некоторым свойствам навигатора.
Каковы ограничения:
1. Невозможно загрузить JS между доменами.
2. Код внутри работника не может получить доступ к DOM.
3. В разных браузерах реализация Worker разная. Например, FF позволяет создавать новых воркеров, а Chrome — нет.
4. Не каждый браузер поддерживает эту новую функцию.
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.