#javascript #web-worker
#javascript #web-worker
Вопрос:
Часть моей программы включает синтаксический анализ текста в структуры данных, которые используют ссылки на другие объекты внутри структуры. Из-за того, как это вписывается в программу, это был бы идеальный кандидат для WebWorkers, поскольку это можно сделать, пока вычисляются другие вещи, и не полагается на какие-либо другие данные, кроме тех, что переданы в него.
Давайте, например, воспользуемся следующим кодом webworker:
self.onmessage = (e) => {
let a;
let b;
let c;
a = {
obj1: b,
obj2: c
}
b = {
obj1: a,
obj2: a
}
c = {
obj1: b,
obj2: b
}
let myArr = [a, b, c];
self.postMessage(myArr);
}
в настоящее время, если я создаю это в web worker и возвращаю myArr
, obj1 и obj2 каждого из элементов не определены. Есть ли какой-либо способ получить эти ссылки из webworker?
Комментарии:
1. Можете ли вы
JSON.stringify(myArr)
в worker, а затемJSON.parse(e.message)
в main file?2. Хм, странно. Я думал, что это то, что JS делал в любом случае за кулисами, но я думаю, что нет. В любом случае, это на самом деле не работает. Даже после изменения кода для создания экземпляра a, b и c с использованием класса, просто кажется, что он проходит через дерево и копирует значения объекта, Т.Е.: если я внесу изменения в
b
thena.obj1
(какие ссылки b), это изменение не отразится
Ответ №1:
Хорошо, я понял это. Я неправильно понимал, как работают ссылки, и это приводило к моим ошибкам.
проблема заключалась в том, что я переназначал объекты и разбивал ссылки, прежде чем отправлять их обратно в основной поток.
Поэтому вместо
let a;
let b;
a = {ref: b}
b = {ref: a}
В приведенном выше примере b
значение начинается с undefined , что означает, когда мы присваиваем его a.ref
, a.ref = undefined
, и когда мы присваиваем b.ref = a
b
сейчас b = {ref: {ref: undefined}}
Чтобы исправить это, мне нужно было убедиться, что переменные были сначала назначены их объектам
let a = {ref: null}
let b = {ref: null}
a.ref = b;
b.ref = a;
Как только я исправил это, казалось, все работало нормально, и b
теперь изменения обновляются a.ref
в основном потоке. Это также было бы исправлено, если бы я просто объявил переменные как let a = new SomeClass()
Если вы столкнулись с подобной проблемой, НЕ ИСПОЛЬЗУЙТЕ JSON.stringify()
! Поначалу может показаться, что это работает, но на самом деле это глубокое копирование ваших ссылок на другие объекты, что означает, что изменение на b
фактически не будет обновляться a.ref
, поскольку a.ref
теперь это просто копия b
, а не ссылка.