Подтвердить что ты не робот

Передача объектов веб-работнику

Я пытаюсь передать объект веб-работнику через функцию postMessage.
Этот объект представляет собой квадрат, который имеет несколько функций, чтобы нарисовать себя на холсте и некоторых других вещах. Веб-работник mus возвращает массив этих объектов.
Проблема в том, что когда я вызываю функцию postMessage с этим объектом, я получаю эту ошибку:

Uncaught Error: DATA_CLONE_ERR: DOM Exception 25

Я получаю это как отправку объекта рабочему, так и наоборот. Я думаю, что ошибка связана с тем, что javascript должен сериализовать объект, но не может этого сделать, потому что объект имеет встроенные функции.

У кого-нибудь была подобная проблема? Вы знаете какой-то рабочий стол? Спасибо заранее.

4b9b3361

Ответ 1

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

При отправке объектов веб-рабочим объект сериализуется и затем десериализуется в веб-работнике, если объект является сериализуемым объектом.

Это означает, что методы для объектов, которые вы отправляете своему веб-рабочему, не являются тем, что может быть передано веб-работнику (в результате чего вы столкнулись с ошибкой), и вам нужно будет предоставить необходимые методы/функции к объектам на стороне веб-рабочего окружения и убедитесь, что они не являются частью объекта, который передается веб-работнику.

Ответ 2

Как вы подозревали, что объекты с функциями не могут быть опубликованы. То же самое касается объектов с рекурсивными ссылками, но в некоторых браузерах это изменилось в последнее время. Вместо того, чтобы рисковать делать ручную и дорогостоящую сериализацию для каждого сообщения, вы можете выполнить тест в начале вашего script, чтобы определить, какие функции использовать для отправки/получения данных.

У меня была такая же проблема и она была решена, переместив почти весь код в рабочего и просто удерживая рендерер (обертывающий 2d-средство визуализации контекста) в основном потоке. В рабочем я сериализую различные призывы рисования, предназначенные для холста, только для чисел в массиве (типизированном). Затем этот массив отправляется в основной поток.

Так, например, когда я хочу нарисовать изображение, я вызываю метод drawImage() на мой рабочий экземпляр рендеринга у рабочего. Вызов преобразуется в нечто вроде [13,1,50,40], которое соответствует перечислению метода draw, уникальному идентификатору изображения и его координатам xy. Несколько вызовов буферизуются и помещаются в один и тот же массив. В конце цикла обновления массив отправляется в основной поток. Принимающий основной экземпляр визуализатора анализирует массив и выполняет соответствующие вызовы рисования.

Ответ 3

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

Вам нужно будет определить методы в веб-рабочем script. Одним из способов является определение importScripts класса и вручную установить свойство __proto__ всего, что вы получаете. В моем случае я хотел передать объект grid, определенный в grid.js (yup, я работал над 2048), и сделал это так:

importScripts('grid.js')

onMessage = function(e) {
  e.data.grid.__proto__ = Grid.prototype;
  ...
}

Ответ 4

Реальная проблема с объектом и веб-работниками связана с методами этих объектов. Объект не должен иметь методы только свойств.

Пример:

var myClass = function(){
    this.a = 5;
    this.myMethod = function(){}
}
var notParseableObject = new myClass();


var myClass2 = function(){
    this.a = 5;
}
var parseableObject = new myClass2();

Первая не работает (с указанным сообщением об ошибке) с postMessage, а вторая будет работать.

Ответ 5

взгляните на плагин vkThread

http://www.eslinstructor.net/vkthread/

он может передать функцию рабочему, включая функцию с контекстом (метод объекта). Он также может передавать функции с зависимостями, анонимными функциями и лямбдами.

- Вадим

Ответ 6

Когда вы передаете данные веб-работнику, копия данных производится с помощью структурированного алгоритма клонирования. Он указан в HTML5 (см. § 2.9: Безопасная передача структурированных данных).

MDN имеет обзор поддерживаемых типов. Поскольку функции не поддерживаются, попытка клонирования объектов, содержащих функции, будет поэтому генерировать исключение DATA_CLONE_ERR.

Что делать, если у вас есть объект с функциями?

  • Если функции не актуальны, попробуйте создать новый объект, содержащий только те данные, которые вы хотите перенести. Пока вы используете только поддерживаемые типы, отправка должна работать. Используя JSON.stringify и JSON.parse также может используется как обходной путь, поскольку stringify игнорирует функции.

  • Если функции важны, нет никакого переносного способа. Существуют попытки использовать комбинацию toString и eval (например, используется jsonfs библиотека), но это не будет работать во всех случаях. Для экземпляров он будет разбит, если ваша функция - это собственный код. Также закрыты проблемы.