Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
949 views
in Technique[技术] by (71.8m points)

angularjs - Is it possible to run Angular in a web worker?

I am build a SPA app with angular and I would like to have my Angular service "WebService" shared with a web worker. The objective is to have one "WebService" shared so that I can use the same service in the background (in the web worker) and in the front-end (the angular app). Is this feasible ?

Additional info: the idea here is for the synchronisation of data on the remote server, so you have the main app working with an "online|offline" mode, saving the data to the local web-storage and|or to the remote server (using the "WebService") and the worker transparently using the same service to sync the data...

Could you show some code to run an app in a worker ? Thank you for your feedback

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...