Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 webworkers

All the articles and guides I could find about webworkers in angular 2 focus on making the entire application run inside the weborker. Is it possible to create just a single service utilizing webworkers?

Going by the classical example of webworkers, could someone show me how to create a service that calculates the factorial of the number using webworkers?

like image 914
Tomasz Kula Avatar asked Oct 08 '16 07:10

Tomasz Kula


1 Answers

New Version

Based on the solution that you can find here, I have build a simple class that use a WebWorker to complete his tasks.

You neet 3 files to have an working Worker.

  1. file-loader.d.ts - need to load WebWorker files

    declare module "file-loader?name=[name].js!*" {
      const value: string;
      export = value;
    }
    
  2. background-worker.ts - class avaliable in your application

    import * as workerPath from "file-loader?name=[name].js!./web-worker-example";
    
    
    class BackgroundWorker {
    
        constructor() {
            let worker = new Worker(workerPath);
            worker.onmessage = this.handleMessage;
            worker.postMessage('Caller: Help Me for background Work');
    
            // Message content can contain only Javascript Objects
            //
            // For Documentation:
            // https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage
            //
        }
    
        private handleMessage( this: Worker, message: MessageEvent ) {
    
            console.log( message.data );
    
            switch( message.data ) {
            case 'Worker: Working':
                // ... Something To Do ...
                break;
            case 'Worker: Ok, I will Do It':
                // ... Something To Do ...
                break;
            case 'Worker: No, I can not':
                // ... Something To Do ...
                break;
            case 'Worker: Done':
                this.terminate();
                break;
            }
        }
    }
    
  3. web-worker-example.ts

    // ****************************************************************** Worker Bridge
    // self is a keyword: Reference to this Worker 
    self.onmessage = bridge;
    
    function bridge( message: MessageEvent ) {
        HandleWork( message.data );
        CallBack('Done');
        // use:
        //       self.close();
        // if you need to terminate worker from Worker Environment.
    }
    
    function CallBack( message: string ) {
        self.postMessage('Worker: ' + message, undefined);
    }
    
    // ****************************************************************** Worker Body
    function HandleWork( workTask: string ) {
        if( workTask == 'Caller: Help Me for background Work' ) {
            CallBack('Ok, I will Do It');
    
            DoVeryComplexWork();
            return;
        }
    
        CallBack('No, I can not');
    }
    
    function DoVeryComplexWork() {
    
        // ... Something To Do ...
    
        // Example:
        for( let i: number = 0; i < 1000000000; i++ ) {
            if( i % 100000000 == 0 ) {
                CallBack('Working');
            }
        }
    }
    

To start Worker, just instantiate worker new BackgroundWorker() and take a look at the console.

Old Version

I had your same problem and solved it by building a service that extends a class of WebWorker. In practice the service work by passing to the WebWorker two things, data and a function that elaborate the data.

I posted an example on GitHub. All the required logic is in the Following two files.

fibonacci-worker.service.ts

worker.ts

Take a look at app.component.ts for call methods.

Regards.

like image 82
Alexander Paul Avatar answered Sep 28 '22 00:09

Alexander Paul