I'm playing around with web workers. I have some medium sized data objects which have operations which take a decent amount of time. Web Workers seem like a good way to parallelize those operations but I'm finding it difficult to choose the best way to pass them to a web worker. Web workers can serialize and deserialize the objects but that leaves them stripped of their class methods. I really want to use their methods of course.
The question is what is a good way to handle reattaching their methods? Clearly one could just copy the methods on to the object passed in but this implies that we know what kind of object we got. To make matters more difficult some objects contain data of other classes meaning we need to reattach methods to those. The first thing that comes to mind is implementing an alternative constructor for each class which takes a JSON object as the parameter. The alternate constructor can then recursively call the JSON constructor for any data member.
Then the problem of how do I choose the correct constructor in the beginning The approaches I've thought of include:
Does anybody have a better idea?
Apparently, all I really needed to do was understand the __proto__
property of Javascript. This can re-establish the availability of class methods for an object after the object is passed to a web worker or retrieved from local storage.
function reattachMethods(serialized,originalclass) {
serialized.__proto__ = originalclass.prototype;
}
The issue with some of the above mentioned solutions is that you end up remaking/copying objects even though you already have all of the data in the correct format. If you have an object containing n elements then that is n elements that need to be copied into the new object after that n objects was serialized and sent from the browser to the web worker. This is obviously not ideal. Double underscore proto was a nonstandard feature which was implemented in all the major browsers and has been announced as part of the next javascript standard.
While the above was true for 2013 the JavaScript language has had many updates since then. If you were attempting the same operation today there are now language provided methods which are recommended to use instead. __proto__
has become deprecated and its use is now discouraged.
In particular, Object.getPrototypeOf(object)
and Object.setPrototypeOf(object, prototype)
take over the role.
class LNode {
constructor(value, next = null) {
this.value = value;
this.next = next;
}
size() {
return 1 + (this.next === null ? 0 : this.next.size());
}
}
let test = new LNode(1, new LNode(2));
test.size(); //2
Object.getPrototypeOf(test); //{constructor: ƒ, size: ƒ}
let bareLinkedList = {value: 1, next: {value: 2, next: null}};
bareLinkedList.size //undefined
Object.setPrototypeOf(bareLinkedList, LNode.prototype);
Object.setPrototypeOf(bareLinkedList.next, LNode.prototype);
bareLinkedList.size(); //2