2016-08-04 2 views
3

Я передаю пустой массив рабочему, который должен заполнить массив и вернуть его - я знаю, что есть другие способы сделать это, но меня больше интересует, почему он не работает , чем заставить его работать.Javascript worker.postMessage сжимает пустой массив

Основной код:

var arr = new Array(4) 
console.log(arr.length)//outputs 4 
var worker = new Worker("whatever.js") 
worker.postMessage(arr) 

Код работника

self.onmessage = function(msg){ 
    console.log(msg.data.length)//outputs 0 
} 

Если я прохожу в населенной массиве, он работает. Если я даже установил единственную запись массива в значение, он будет работать.

Почему функция postMessage сбрасывает ненулевые, но пустые массивы, есть ли способ избежать этого? (кроме указания вручную значения) .

Я использую Windows 7 и Chrome 51

ответ

0

Данные копируются в рабочий через structured cloning algorithm, так что ваш работник не получают точный массив, который вы создали, что бы нить небезопасных операций, как массивы являются ссылочный тип. Это случай, когда документы MDN являются неполными, вообще говоря, за некоторыми исключениями, алгоритм сглаживания клонирования эквивалентен JSON.parse(JSON.stringify(x)), но это исключение, поскольку JSON.parse(JSON.stringify(new Array(4))) дает [null, null, null, null] по меньшей мере в хром и ff.

Странное поведение здесь, вероятно, частично связано с тем, что на самом деле нет смысла создавать массивы с пустыми слотами, даже нет никаких указаний, например. new Array(4).forEach(i => console.log('foo')); ничего не делает. Таким образом, алгоритм структурированного клонирования генерирует пустой массив.

Обратите внимание, что структурированный алгоритм клонирования не часть спецификации JavaScript, это скорее часть HTML 5 spec и, насколько я могу сказать, не дает много деталей, так что я не совсем уверен, как это работает, но, похоже, сосредоточено на таких вещах, как fileData и Blobs. Обратите внимание, что клонирование массива-буфера составляет часть Ecmascript spec. Все это имеет какой-то смысл, рабочие имеют огромное ограничение производительности для служебных данных связи (именно поэтому были предложены конструкции с разделяемой памятью) в немалой степени из-за того же алгоритма. Таким образом, вычисление, которое вы хотите сделать в них, должно быть достаточно интенсивным, чтобы перевесить стартовые и коммуникационные штрафы. Таким образом, имеет смысл, что канал связи более сфокусирован на тех низкоуровневых (по существу двоичных в блочных случаях) конструкциях данных.

+0

спасибо за ответ - я использую библиотеку под названием Сленг, она использует этот шаблон для возврата повторяющейся строки, например, новый массив (4) .join («1») вернет «1 1 1», его используется аналогично в другом месте, где я должен передать его работнику. Как я уже сказал в своем вопросе, меня больше интересует, почему он не копируется как определено, вместо того, чтобы снова найти «исправление» –

+0

@ ZackNewsham, на самом деле нет смысла делать это, 'String.prototype .repeat' является стандартным, и хотя довольно недавнее тривиально для полиполнения. Я сделал бы это на редкость и использовал бы более распространенные шаблоны. Интересный краевой кейс, который вы нашли! –

+0

Полезно знать о 'String.prototype.repeat' К сожалению, я работаю над проектом, который требует, чтобы я конвертировал некоторые библиотеки в рабочих - это долгая история, поэтому я не могу реально изменить тестируемый код, если у меня нет к. Что касается того, что это бессмысленно, я думал, что смысл этого заключается в том, чтобы сразу же выделить массив правильного размера, а не многократно изменять размер с помощью 'Array.prototype.push' - я знаю, что в этом случае это мало чем отличается от его копирования в работник в любом случае –

Смежные вопросы