Как стать автором
Обновить

Комментарии 56

Спасибо, в дополнение отмечу, что поддерживается сие чудо Safari, Chrome, Opera и Firefox. Ослик как обычно — хотя включили в Internet Explorer 10 Platform Preview 2. Web worker-ы поддерживаются Safari под iOS 5, и Android-ом начиная с 2.0
Firefox 3.6 не поддерживает, кстати
А не пробовали для FF 3.6 не устанавливать setRequestHeader? Мне помогло :)
что не удивительно, так как вышел он аж 21 января 2010 пруф, а вторая стадия активной разработки и внедрения html5 началась незадолго до этого в 2009 пруф
Не могли бы вы пояснить для новичков, почему надо отправлять синхронные запросы методом POST? Что значит «адекватный ответ»?
суть в том, что воркер может завершится ранее, чем будет получен ответ и если в качестве обработчика будет стоять ф-ция из воркера, есть вариант не предсказуемого поведения браузера, посколько колбек ф-ция может уже быть недоступна
Ещё один вопрос от новичков: как функия воркера может быть недоступна? Если в ней был создан колбек, который используется асинхронным запросом, разве такую функцию может удалить gc? Или есть какие-то особенности про обработке воркеров?
Я не особо гуру в механизмах JS, но в приведенном мной примере колбэк определен не в воркере, а в объекте аякса, к тому моменту, как объект возвращает значение его уже некуда возвращать. Асинхронный запрос подразумевает, что скрипт не останавливаясь выполняется дальше, а дальше после отсыла запроса, идет возвращение значения workerAjax.postMessage(objEx); и воркер удаляется(наверно). Поэтому колбэк определен в основном потоке, а не в воркере, в который нужно будет импортировать еще и скрипт, в котором содержится вызываемая колбэк функция. Наверно, как-то так. :)
Мне кажется использование workers для AJAX вызовов это неадекватное их использование, т.к. в этом случае асинхронность обеспечивает сам ActiveX объект, который делает HTTP запросы. А смысл появляется только в случае ресурсоемкого JavaScript кода, т.к. весь JavaScript в браузере выполняется в одном потоке. Если бы до появления workers все AJAX запросы были синхронными, то большей частью современных веб-приложений невозможно было бы пользоваться.
А теперь о важном, о том, чего нет ни в одной статье про работников: для того чтобы получить адекватный ответ при использовании технологии AJAX, необходимо отсылать СИНХРОННЫЕ запросы методом POST.

извините, не верю
а вы попробуйте, синхронные и асинхронные варианты в разных браузерах
if (!!window.Worker)

Интересная конструкция…
Стандартная ситуация — когда нужно проверить на существование.
! — «не», просто преобразует в булевый тип

!!- вернет булевый тип, и реальное состояние дел. (если там что-то было: Объект, массив, строка — true;
null, undefined, false — false)

если worker'а нет, то if (window.Worker) вернет false. Если есть, то вернет true. Не вижу проблемы
Да, но это принудительное приведения значения к булю. Т.к в оригинале есть window.Worker есть это будет функция, если нету то undefined, это не более чем хорошая практика.
if (!!window.Worker)
Эта пять.

Ещё надо добавить, что HTML5 позволяет создать Web Worker и без внешнего файла с помощью blobBuilder'а:

var worker = new Worker(
	window.URL.createObjectURL(
		new BlobBuilder().append(
			"onmessage = function(e) { postMessage('hello habrahabr'); }"
		).getBlob()
	)
);

worker.postMessage();

Подробнее на HTML5Rocks
Ну тогда уж и ~~ запишите в коллекцию )

Math.floor(5.6) == ~~5.6
Насчёт синхронности/асинхронности — разницы нет. Потому что все события работают мгновенно и быстро. То есть, если у вас синхронный запрос, все события просто навсего обрабатываются внутри *request, а если асинхронный, то вам это нужно делать самому — подписываться. Но в этом нет ничего тормозного — работать будет также быстро, как и синхронный.
Ну конечно нет, а то что синхронный запрос подвешивает браузер до завершения запроса это такие мелочи
Вероятно, вы не поняли. Я тут хотел выразить мысль о том, о чём пишет автор — он пишет, «что нужно применять именно синхронный запрос». И уточняет, что из-за скорости.

Я это опровергаю, говоря то, что асинхронный будет так же быстр (то есть, без разницы).

То есть, я именно за асинхронность. Синхронность устарела и не применяется уже почти нигде.
Посмотрите внимательней,

Автор пишет про синхронный запрос не из за скорости, а из за бага насколько я понимаю.
Скорость будет за счёт того что сами воркеры асинхронные и работают в параллели.
То есть, баг в том, что процесс Worker выйдет после выполнения работы, не дождавшись ответа асинхронного запроса? Или в чём именно баг?
>>Для того чтобы получить адекватный ответ при использовании технологии AJAX, необходимо отсылать СИНХРОННЫЕ запросы методом POST

То есть любой другой вариант просто будет не рабочий по словам автора, хотя я вот в хроме налабал пример, ещё чутка потестирую и в основной поток коммент с примером выложу.
нет, не из-за скорости, где это я такое написал? смысл в том, что при асинхронном запросе воркер возвращает результат не дождавшись ответа с сервера.
При использовании данной технологии для выполнения простых действий выигрыш в скорости будет минимален. Однако при сложных вычислениях можно существенно ускорить работу системы.
это написано про воркеры в целом, а не про аякс
Это написано в том же обзаце, что и про POST-баг-синнхронность-асинхронность, поэтому было сразу видно, что это как-бы уточнение по поводу этой темы.

Для того, чтобы это относилось ко всей теме, это нужно написать отдельным абзацем, наверное.

Вот сейчас всё становится ясно, спасибо.

— А насчёт скорости работы Worker для системы в целом — всё правильно, согласен. Спасибо за перевод, читал по англ. полгода назад про эти вокеры, удобная вещь, как-бы независимые ветки (Thread).
Это не перевод, согласен, прежде чем писать статью, я прочитал курс на intuit`e по html5, но больше статей не изучал, все что написано — добыто своими силами
Действительно, имела место речевая ошибка. Немного подправил. Надеюсь, больше не будет возникать двусмысленности в написанном.
Ура.
Автор обновите пост, в webkit браузерах работает

Для основного файла:
  if (!!window.Worker){
    var worker = new Worker('worker.js');
    worker.postMessage('Hellow World');
    worker.onmessage = function (e){
      alert(e.data);
    };
  }


Для worker:

onmessage = function(e){
  transport = new XMLHttpRequest();
  transport.open('GET', 'data.txt', true);
  transport.onreadystatechange = function(){
    if(transport.readyState == 4){
      postMessage(transport.response);
    } 
  };
  transport.send();
};


Ну а в data.txt пихаем просто текст на тест, я пихал «testing123»
а мой код работает во всех браузерах, поэтому смысла в нем что-то менять пока не вижу
Автор вы пишете статью или балаган устраиваете?

Поясняю, вы писали

1) А теперь о важном, о том, чего нет ни в одной статье про работников: для того чтобы получить адекватный ответ при использовании технологии AJAX, необходимо отсылать СИНХРОННЫЕ запросы методом POST.


Я код выше написал, который опровергает ваши слова, я же не сказал что он работает везде, я уточнил сразу что только в webkite, в остальных либо начнёт работать со временем либо не начнёт, о нормальном варианте людям знать не мешает.

2) Причина проста: при асинхронном запросе воркер заканчивает работу не дожидаясь ответа сервера. Логического объяснения почему не шлется методом GET я так и не нашел.


Опять же мой код эти слова опроверг, и про GET и про заканчивает работу.
нормальный вариант — это тот, который работает везде. Это как свежесть — она только одна ©
да, и стоит наверно все-таки проверять статус ответа сервера, а то state может быть 4, а вот status 404…
Это пример, исключительно для данного бага, который в вэбките не подтвердился.
Накой чёрт ему писать нормальный callback и прочие обвязки?
Чтобы вам некчему придратся было?

Ну уж извините, я его писал с другой целью.
Нормальный вариант это чистый вариант, о котором я и прошу сделать обновление, причём дополнение а не похерить пост к чертям.
Научитесь воспринимать критику нормально.

От того что в 6м IE в давние времена все и всё делали через зад, никто не называл это нормальным вариантом, это называлось костылями.
уважаемый yui_room9, приведенный мной пример объекта для обмена аякс запросами не содержит костылей, а реализует одну из самых распространенных кроссбраузерных функций создания объекта XMLHttpRequest. Как только все браузеры начнут поддерживать унифицированную технологию создания объектов, я буду первым, кто перепишет свой класс и упростит его. Но пока, к моему величайшему сожалению, это не так, посему я, подчеркиваю еще раз — я, реализовал обмен данными именно таким образом. Если вас он не устраивает я на нем не настаиваю, делайте как хотите. Для меня главное, что он работает во многих современных браузерах. Кстати, тот объект который есть переводится с веб воркеров на обычный код, фунциклирующий в IE, буквально несколькими строками.
Я ничего не имею против вашего лично метода и вас лично.

Я просто попросил вас сделать дополнение к фразе

для того чтобы получить адекватный ответ при использовании технологии AJAX, необходимо отсылать СИНХРОННЫЕ запросы методом POST


О том что webkit браузеры поддерживают асинхронный запрос в воркере.
Что странного в этой просьбе?
Вы же делитесь информацией с людьми, зачем же часть информации утаивать?
обновил.
Спасибо
Да, не очень внятно описано, почему именно нельзя использовать асинхронный запрос. Однако статья в целом полезная.
дополнил статью, надеюсь, получилось понятно
Не сочтите за придирчивость, просто в глаза бросилась опечатка – «Hellow» пишется без «w». =)
исправлено :)
Странно, у меня работает асинхронный GET в воркере и ответ возвращается в firefox 8, что я делаю не так?
Пример от yui_room9 тоже отлично работает, только postMessage(transport.responseText);
Вот :) +1 Браузер, я в FF 8 не проверял.
Всёже это глюк а не нормальное поведение с синхронным запросом.
опера 11.52 chrome 15.0.874.121 m возвращают 'undefined', обновил ff до 8 версии, он тупо вылетает на строке создания воркера
var workerAjax = new Worker('/JS/workers/ajaxWorker.js');
при этом не выдает никакой ошибки… О_О
нашел консоль в этом мегобраузере… пишет
Ошибка: Could not get domain!
Источник: localhost/JS/workers/mainWorkers.js
Строка: 39

если адрес скопировать то файл нормально открывается, да и другие браузеры нормально отрабатывают, один фф чего-то артачится…
как оказалось, касяк в самой мазиле подробнее здесь
А ещё можно сказать, что воркеры не просто позволяют передавать любые объекты, а ещё их клонируют. Поэтому если передавать большой объём данных между потоками, то будет заметное блокирование GUI браузера в момент приёма данных от воркера.
У меня есть скрипт ~20мб, в котором просто декларирование трёх больших массивов со строками и числами. Если его подключать просто через создание тега script, то исполнение кода занимает около 3 сек с блокированием на это время GUI. Если делать через воркер: запустить воркер, внутри вызвать importScripts() и выдать «наружу» только данные, то время до готовности увеличилось вдвое — 7-8 сек, но при этом GUI блокируется только в самом конце на 1-2 сек, когда приходит ответ от воркера. Так что в моей ситуации воркеры практически не помогли.

P.S.
Тестировал в Chrome 15 с файловой системы (вообще без веб-сервера), так что временем загрузки скрипта можно пренебречь.
20мб — это большой и довольно редкий случай, для мелких объёмов время до готовности тоже удваивается, а критичного времени блокирования GUI для них нет — поэтому для них ситуация даже ухудшилась.
Функцию provXmlHttp можно улучшить, если в первую очередь проверить наличие XMLHttpRequest объекта и использовать его, если возможно. И только, если он не поддерживается, тогда использовать ActiveX. Типа как сначала проверяем предпочтительный вариант, и если не работает, то переходим к fallback решению.
… Таких файлов может быть столько сколько нужно... (Из поста)
Хочется уточнить, что 256 — максимальное количество работников. Потом просто стёк переполняется и пишет ошибку:
Maximum number of Web Worker instances(256) exceeded for this window.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории