I'm trying to create my first web worker in javascript. I got a object called predictor it has methods and attributes using prototype as you can see here:
function Predictor(historical, type) {
this.historical = historical;
this.type = type;
this.NN = this.generateNN(this.historical);
}
Predictor.prototype.getMaxTime = function (historical) {
return historical.length;
};
I'm using the library synapic.js, with this you can create neuronal networks (NN). Sometimes train a NN it is a expensive progress and the web browser is freezing while the script is finishing the train.
I read about the web workers in order to avoid this problem. I tried to postMessage
with the object Predictor
and execute predictor.train()
in the worker, but the browser said that Predictor
it is not a Transferable
or Clonable
object. As I understrand the messages must be converted to JSON and I can not pass my object as I can do in others languages serializing the class.
The second that I tried it is to create the predictor in the web worker and save it in the worker. I used the method importScripts('../../lib/synaptic/synaptic.js')
and importScripts('../model/predictor.js')
to use the library and the class that I create but the browser says:
Uncaught ReferenceError: synaptic is not defined
Can I send my object Predictor
as param in the function postMessage
?
What is the best way to fix it?
Predictor
over message isn't gonna workThe problem is that just passing the Predictor
would not be enough even if you managed to do it. Do not forget that the whole library must be present when working with predictor!
When you pass objects to web worker, only their own properties are sent, not those from the prototype. So for example the Predictor.prototype.getMaxTime
wouldn't pass.
synaptic is not defined
error (Spoiler: not your fault)Many of mine questions as well as other were caused by the same developper's mistake: they use window
instead of self
.
In web worker, self
contains the global scope as well as the worker methods (eg. postMessage
). In browser, self == window
.
So to fix your problem, replace window
with self
in Synaptic sources.
Search query in their GitHub repo: https://github.com/cazala/synaptic/search?utf8=%E2%9C%93&q=window
I'm not 100% sure about this, but this might do the trick. But it also might confuse the hell out of libraries that are aware of how workers work:
// Make global variable window that refers to global scope
self.window = self;
// Yes you can pass multiple paths at once
importScripts('../../lib/synaptic/synaptic.js', '../model/predictor.js');
// Should work. Next time make a test case so I don't have to shoot blindfolded
...