Web Worker's addEventListener() & postMessage() Not Working Inside Class Constructor

Topics: General
Mar 27, 2014 at 7:09 PM
Edited Mar 31, 2014 at 3:00 PM
In TypeScript 0.9.5 (not 0.9.7/RC1 due to known issues), I'm trying to use addEventListener() & postMessage() inside of the constructor for a Web Worker class. However, it's not working as I don't see the console message from the posted data, so I'm looking for any suggestions as I've already tried to take into this known issue with the library definition which makes self a Window object instead of Worker object.

Here's my example code with my various attempts:

app.ts file
class Greeter {
    start() {
        var worker = new Worker('worker.js');

        worker.addEventListener('message', (e) => {
            console.log('Worker said: ', e.data);
        }, false);

        worker.postMessage('Hello World');
    }
}

window.onload = () => {
    var greeter = new Greeter();
    greeter.start();
};
worker.ts file
class Workman {
    self2: Worker;

    constructor() {
        // Attempt #1: This fails.
        /*
        self.addEventListener('message', function(e) {
            (<any> self.postMessage)(e.data);
        }, false);
        */

        // Attempt #2: This also fails.
        /*
        addEventListener('message', (e) => {
            (<any> postMessage)(e.data);
        }, false);
        */

        // Attempt #3: This also fails.
        /*
        var listener = function (e) {
            (<any> self.postMessage)(e.data);
        }
        self.addEventListener('message', listener);
        */

        // Attempt #4: This also fails.
        /*
        var that = this;
        self.addEventListener('message', that.OnMessage);
        */

        // Attempt #5: This also fails.
        /*
        ((self: Worker) => {
            self.addEventListener('message', function (e) {
                (<any> self.postMessage)(e.data);
            }, false);
        });
        */

        // Attempt #6: This also fails.
        /*
        self: Worker;
        self.addEventListener('message', function (e) {
            (<any> self.postMessage)(e.data);
        }, false);
        */

        // Attempt #7: This also fails.
        /*
        this.self2.addEventListener('message', function (e) {
            (<any> this.self2.postMessage)(e.data);
        }, false);
        */
    }

    OnMessage = (e) => {
        (<any> postMessage)(e.data);
    }
}

// SUCCESS: This works!
/*
addEventListener('message', (e) => {
    (<any> postMessage)(e.data);
}, false);
*/
Note, in my testing, I only had one addEventListener() section active at a time.
Coordinator
Apr 2, 2014 at 12:46 AM
You might want to take a look at the changes we have done recently in develop to add a new lib.webworker.d.ts. This however will mean that you need to split your code into two sections one for webworker code, and one for everything else. Please see the discussion on [issue#2325] (https://typescript.codeplex.com/workitem/2325) for more details.

Here is the reference to the change for splitting the library file:
https://typescript.codeplex.com/SourceControl/changeset/5d29bd2b2570bef3e1fe27902f6064c07c8eca22
Apr 2, 2014 at 1:05 AM
How can your code work when you haven't create an instance of your class? The constructor doesn't run by itself. Should it not be like this:
class Workman {
    constructor() {
        addEventListener('message', (e) => {
            this.OnMessage(e);
        }, false);
    }

    OnMessage = (e) => {
        (<any> postMessage)(e.data);
    }
}

new Workman();
--- or ---
class Workman {
    private static __sctor = (() => {
        addEventListener('message', (e) => {
            Workman.OnMessage(e);
        }, false);
    })();

    static OnMessage = (e) => {
        (<any> postMessage)(e.data);
    }
}
Apr 2, 2014 at 12:43 PM
@mhegazy: I understand and I'll keep that in mind then, so thanks for letting me know.

@jamesnw: Hmm, good point! I was under the impression that the class's underlying constructor was automatically invoked when creating the Worker object, but that is very likely the reason things aren't working, so I'll give your suggestion a try and thanks for the help.