Передача больших объемов данных между веб-рабочим и основным потоком

Есть ли способ передавать большие объемы данных (несколько МБ) между веб-воркером и основным потоком? Я работаю в проекте, где мне нужно загрузить файлы, немного изменить их, а затем каким-то образом позволить пользователю загрузить измененный файл. Я нашел следующие способы передачи данных между веб-воркером и основным пользовательским интерфейсом.

  1. Обычным методом postMessage.
  2. Использование переносимых объектов (только в Chrome)
  3. Создайте ссылку URL-адреса на большой двоичный объект и отправьте только URL-адрес (работает в Chrome, а также в других?)

Я думаю, что (1) подходит для отправки небольших объектов, но это занимает много времени и места при работе с файлами размером более нескольких МБ, поскольку он сериализуется и отправляется как JSON. Chrome предлагает способ передачи данных с помощью переносимых объектов, где данные не нужно копировать. К сожалению, пока это только функция Chrome, так как в противном случае она бы послужила моей цели.

Последнее, что я обнаружил, это то, что работник создает URL-адрес большого двоичного объекта с помощью self.webkitURL, а затем передает только URL-ссылку в пользовательский интерфейс. Это работает хорошо, я могу дать URL-адрес пользователю, и он сможет загрузить файл. К сожалению, я не нашел способа сделать это в Firefox, возможно ли это?

Есть ли другие методы, которые можно использовать для передачи данных между рабочими и основным потоком?


person Erik    schedule 05.10.2012    source источник


Ответы (2)


Firefox / Opera / Chrome в настоящее время поддерживают разновидность веб-воркеров под названием Transferable Objects. который работает очень быстро, а также чрезвычайно прост в настройке. Здесь мы отправляем ww (веб-воркер) выделенный браузером массив, который заполняется ww и возвращается обратно в браузер. Это передается по ссылке, а не по копии: browser ‹-› ww

Со стороны браузера:

var huge_array = new Float32Array(BIG_HUSKY_SIZE);

// worker.postMessage(huge_array.buffer);                      // old way
   worker.postMessage(huge_array.buffer, [huge_array.buffer]); // new Trans Obj

а затем внутри веб-воркера:

self.onmessage = function(e) {

      var flt_arr = new Float32Array(e.data);

    //  typically you might want to populate flt_arr here

    //  now send data structure back to browser

    // self.postMessage(flt_arr.buffer);                    // old way
       self.postMessage(flt_arr.buffer, [flt_arr.buffer]); // new Trans Obj way
}

Просто поместив объект данных в квадратные скобки [здесь], это подскажет js использовать режим переносимого объекта. Это также работает при отправке туда и обратно объектов javascript, содержащих несколько переменных, а не только типизированных массивов.

Цитата:

Переносимые объекты - это объекты, которые не копируются (например, с использованием чего-то вроде структурированного клонирования). Вместо этого данные передаются из одного контекста в другой. «Версия» из вызывающего контекста больше не доступна после передачи в новый контекст. Например, при передаче ArrayBuffer из основного приложения в Worker исходный ArrayBuffer из основного потока очищается и больше не может использоваться. Это значительно повышает производительность отправки данных работнику.

http://html5-demos.appspot.com/static/workers/transferables/index.html https://html.spec.whatwg.org/multipage/workers.html

person Scott Stensland    schedule 02.12.2014
comment
Откуда у вас цитата? - person royhowie; 02.12.2014
comment
цитата от Эрика Бидельмана (штатный сотрудник Google), она появляется, если вы нажимаете на Yo dawg, что это? который отображается вверху URL-адреса, который я перечисляю выше ... его родительская ссылка - updates.html5rocks.com/2011/12/ - person Scott Stensland; 02.12.2014

Согласно этому учебнику WebWorkers, WebWorkers теперь поддерживают передачу объектов File и Blob и практически любого объекта, который может использоваться с структурированным клоном алгоритма ... или, по крайней мере, Chrome делает это, вероятно, потому, что он реализует API FileSystem. Я не знаю, является ли это основной причиной, но я надеюсь, что нет, и на самом деле эта функция реализована в других браузерах ... возможность обрабатывать выбранные пользователем файлы в фоновом режиме - это хорошо.

person Piranna    schedule 08.10.2012
comment
К сожалению, это все еще операция копирования, даже если она, безусловно, увеличивает скорость. - person Erik; 09.10.2012