Question

I am trying to initialize a Breeze manager inside a 'Web Worker'.

RequireJs, knockout, q, breeze are being imported inside the worker.
After a call to:EntityQuery.from('name').using(manager).execute(),
the following error appears:
Uncaught Error: Q is undefined. Are you missing Q.js? See https://github.com/kriskowal/q.

A live preview is uploaded here http://plnkr.co/edit/meXjKa?p=preview
(plunk supports downloading for easier debug).

EDIT -- relevant code
Worker.js

importScripts('knockout.js', 'q.js', 'breeze.js', 'require.js');
define('jquery', function () { return jQuery; });
define('knockout', ko);
define('q', Q); //Just trying to assign q since breeze requests Q as q
require(function () {
var self = this;
this.q = this.Q; //Just trying to assign q since breeze requests Q as q

breeze.NamingConvention.camelCase.setAsDefault();
var manager = new breeze.EntityManager("breeze/Breeze");

var EntityQuery = breeze.EntityQuery;

// Q or q here is defined (TESTED)

var test = function (name) {
    return EntityQuery.from(name)
          .using(manager).execute()  // <-- Here q/Q breaks (I think on execute)
};

var primeData = function () {
    return test('Languages')
            .then(test('Lala'))
            .then(test('Lala2'))
};

primeData();
setTimeout(function () { postMessage("TestMan"); }, 500);
});  

Worker will be initialized on main page as:

var myWorker = new Worker("worker.js");  
Était-ce utile?

La solution

Ok here it goes:

  1. Create a new requireJs and edit the
    isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document)
    to
    isBrowser = false

  2. Create a new Jquery so it uses nothing related to window and generally anything that a WebWorker cannot access. Unfortunatelly i can't remember where i got this Custom JQueryJs but i have uploaded it here "https://dl.dropboxusercontent.com/u/48132252/jqueydemo.js".
    Please if you find the author or the original change link and give credit.

  3. My workerJs file looks like:

    importScripts('Scripts/test.js', 'Scripts/jqueydemo.js', 'Scripts/q.js', 'Scripts/breeze.debug.js', 'Scripts/require2.js');
    define('jquery', function () { return jQuery; });
    require(
    {
        baseUrl: "..",
    },
    function () {
    var manager = new breeze.EntityManager("breeze/Breeze");
    var EntityQuery = breeze.EntityQuery;
    var primeData = function () {
        return EntityQuery.from(name)
                .using(manager).execute()  // Get my Data
                .then(function (data) {
                    console.log("fetced!\n" + ((new Date()).getTime()));
                    var exportData = manager.exportEntities(); // Export my constructed entities
                    console.log("created!\n" + ((new Date()).getTime()));
                    var lala = JSON.stringify(exportData)
                    postMessage(lala); // Send them as a string to the main thread 
                })
    };
    primeData();
    }); 
    
  4. Finally on my mainJs i have something like:

        this.testWorker = function () {
        var myWorker = new Worker("worker.js"); // Init Worker
    
        myWorker.onmessage = function (oEvent) { // On worker job finished
            toastr.success('Worker finished and returned');
            var lala = JSON.parse(oEvent.data); // Reverse string to JSON
            manager.importEntities(lala);  // Import the pre-Constructed Entities to breezeManager
            toastr.success('Import done');
            myWorker.terminate();
        };
    };  
    

So we have managed to use breeze on a WebWorker enviroment to fetch and create all of our entities, pass our exported entities to our main breeze manager on the main thread(import).

I have tested this with 9 tables fully related to each other and about 4MB of raw data.

PROFIT: UI stays fully responsive all the time.
No more long execution script, application not responding or out of memory errors) at least for chrome

*As it makes sense breeze import entities is way more faster than the creation a full 4MB raw data plus the association process following for these entities.
By having all the heavy work done on the back, and only use import entities on the front, breeze allows you to handle large datasets 'like a breeze'.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top