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
Web workers enables JavaScript application to run the CPU-intensive in the background so that the application main thread concentrate on the smooth operation of UI. Angular provides support for including Web workers in the application.
What is a Service Worker? Unlike Web Workers, Service Workers have a dedicated role of being a proxy between the network and the browser and/or cache. Similar to Web Workers, they are registered in the primary JavaScript file as a dedicated worker.
How many web workers can run concurrently JavaScript? A web worker is a JavaScript program running on a different thread, in parallel with main thread. The browser creates one thread per tab. The main thread can spawn an unlimited number of web workers, until the user's system resources are fully consumed.
Web Workers are primarily used for CPU-intensive tasks to be run in the background without any network connectivity required to work on the tasks.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With