Is it possible to run Angular in a web worker?

假如想象 提交于 2019-11-29 07:46:53
Michal Charemza

Yes, it's possible. With a bit of a hack of the web worker environment, you can run Angular in the web worker, and have a module that is used in both foreground and worker Angular apps. This answer takes and and extends code from another of my answers regarding unit testing

In the main app, in a factory/service, you can have something like

var worker = new $window.Worker('worker.js');

Then in worker.js, you can modify the global scope enough to get Angular to load:

// Angular needs a global window object
self.window = self;

// Skeleton properties to get Angular to load and bootstrap.
self.history = {};
self.document = {
  readyState: 'complete',
  querySelector: function() {},
  createElement: function() {
    return {
      pathname: '',
      setAttribute: function() {}
    }
  }
};

// Load Angular: must be on same domain as this script
self.importScripts('angular.js');

// Put angular on global scope
self.angular = window.angular;

// Standard angular module definitions
self.importScripts('worker-app.js');
self.importScripts('shared-module.js');

// No root element seems to work fine
self.angular.bootstrap(null, ['worker-app']);

And you can define shared-module just like any other:

angular.module('shared-module', [])
.factory('SharedFactory', function() {
  return {
    myFunc: function() {
      return 'some-data';
    }
  };
});

In worker-app.js, you can define the main app, using the shared module

var workerApp = angular.module('worker-app', ['shared-module']);

injecting the shared components, for example, into the run callback of the worker app.

workerApp.run(function(SharedFactory, $window) {
  $window.onmessage = function(e) {
    var workerResult = SharedFactory.myFunc();
    $window.postMessage(workerResult);
  };
});

In the foreground Angular app, you can include shared-module.js via a usual script tag, and use dependency injection to access its components as usual

var foregroundApp = angular.module('forground-app', ['shared-module']);
foregroundApp.controller(function(SharedFactory, $scope) {
  // Use SharedFactory as needed
});

To confirm, the instances of shared-module in the foreground and worker app are different.

Yes, it's possible, but think of all the issues you'll encounter. You'd have two different Angular apps, two different contexts (meaning only external data can be shared), and in one context (the service) there's absolutely no need for 99% of Angular's features.

You didn't describe what exactly are you planning to do, but I strongly suggest you consider other options. The standard approach here would be use a server and have a number of API endpoint, which will sort of function as the service you've mentioned. However, if you need a continuous communication with the service, perhaps you could make use of web sockets.

You should probably update your question with more info, because at this point I really can't see any advantages of having another app running as a web worked just to be able to make use of a service.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!