Cómo puede angularJS uso de la web a los trabajadores para ejecutar procesos en segundo plano? ¿Hay algún modelo que se debe seguir haciendo esto?

Actualmente, estoy usando un servicio que tiene la modelo en una web independiente trabajador. Este servicio implementa métodos como:

ClientsFacade.calculateDebt(client1); //Just an example..

En la aplicación, este método envía un mensaje a los trabajadores con los datos. Esto me permite abstraer el hecho de que se lleva a cabo en un hilo separado y también podría proporcionar una implementación que las consultas contra un servidor o incluso uno que hace de esta acción en el mismo hilo.

Ya que soy nuevo en javascript y yo sólo soy el reciclaje de conocimientos de otras plataformas me pregunto si esto es algo que puedes hacer, o tal vez Angular que es lo que estoy usando, ofrece una especie de manera de hacer esto. También esto introduce un cambio en mi arquitectura, ya que el trabajador debe explícitamente empujar cambios en el controlador, el cual, a continuación, las actualizaciones de sus valores y, a continuación, esto se refleja en la vista, soy más de la ingeniería de esto? Es un poco frustrante que los web workers «proteger» a mí mucho de cagarla por no permitirme compartir la memoria, etc.

OriginalEl autor arg20 | 2013-05-23

5 Comentarios

  1. 95

    Comunicación con los Web workers pasa a través de un mecanismo de mensajería. Interceptar estos mensajes que sucede en una llamada de vuelta. En AngularJS, el mejor lugar para poner una web de trabajo está en un servicio como usted ha tomado debida nota. La mejor manera de lidiar con esto es el uso de las promesas, que Angulares funciona increíblemente.

    Aquí es un ejemplo de un webworker en un service

    var app = angular.module("myApp",[]);
    
    app.factory("HelloWorldService",['$q',function($q){
    
        var worker = new Worker('doWork.js');
        var defer = $q.defer();
        worker.addEventListener('message', function(e) {
          console.log('Worker said: ', e.data);
          defer.resolve(e.data);
        }, false);
    
        return {
            doWork : function(myData){
                defer = $q.defer();
                worker.postMessage(myData); //Send data to our worker. 
                return defer.promise;
            }
        };
    
    });

    Ahora lo externo de la entidad que tiene acceso a Hello World servicio no necesita de atención acerca de los detalles de implementación de HelloWorldServiceHelloWorldService probablemente podría proceso de los datos a través de una web worker, sobre http o hacer el procesamiento de allí.

    Espero que esto tenga sentido.

    ¿qué es el doWork.js en var trabajador = new Trabajador(‘doWork.js’); ?
    Es una referencia al archivo js externo que contiene el código para la web-trabajador.
    sí, es posible utilizar servicios como $http en doWork.js?
    Si doWork se llama de nuevo antes de que el trabajador termina, no defer ser sobrescrito? La segunda promesa sería entonces resolver con el resultado de la primera, y la primera promesa que nunca iba a resolver.
    A partir de mi lectura de el código, sí, creo que tienes razón. Este código debe ser modificado para proporcionar una nueva aplazar para resolver cada vez doWork(datos) es llamado.

    OriginalEl autor ganaraj

  2. 16

    Una pregunta muy interesante! Me parece la web trabajador de la especificación de un poco torpe (probablemente por buenas razones, pero todavía torpe). La necesidad de mantener al trabajador de código en un archivo independiente que hace la voluntad de un servicio difícil de leer y presenta dependencias de archivo estático Url en su angulares código de la aplicación. Este problema puede ser mitigado mediante el uso de la dirección URL.createObjectUrl() que puede ser utilizado para crear una dirección URL para una cadena de JavaScript. Esto nos permite especificar el código del trabajador en el mismo archivo que crea el trabajador.

    var blobURL = URL.createObjectURL(new Blob([
        "var i = 0;//web worker body"
    ], { type: 'application/javascript' }));
    var worker = new Worker(blobURL);

    La web trabajador spec también mantiene el trabajador y el hilo principal contextos completamente separado para evitar situaciones fueron interbloqueos y livelocks etc puede ocurrir. Pero también significa que usted no tendrá acceso a su angular de servicios en el trabajador sin un poco de tocar el violín. El trabajador falta algunas de las cosas que(y angular) esperar cuando la ejecución de JavaScript en el navegador, al igual que la variable global «documento», etc. Por «burlarse» de estos navegador requerido características del trabajador que podemos obtener angular para ejecutar.

    var window = self;
    self.history = {};
    var document = {
        readyState: 'complete',
        cookie: '',
        querySelector: function () {},
        createElement: function () {
            return {
                pathname: '',
                setAttribute: function () {}
            };
        }
    };

    Algunas características, obviamente, no funciona, enlaces a la DOM, etc. Pero la inyección de marco y, por ejemplo, los $servicio http funcionarán igual de bien, que es probablemente lo que queremos en un trabajador. Qué ganamos con esto es que podemos ejecutar estándar angular de los servicios de un trabajador. Por lo tanto, podemos unidad de prueba de los servicios utilizados en el trabajador de la misma forma que lo haríamos con cualquier otra dependencia angular.

    Hice un post en el que se profundiza un poco más sobre este aquí y creó un repo en github que crea un servicio que implementa las ideas discutidas anteriormente aquí

    Para angular >= v1.5.7, pensar en añadir yo.Nodo = { prototipo: [] }; ver github.com/FredrikSandell/angular-workers/issues/15

    OriginalEl autor liket

  3. 11

    Me encontré con un completo ejemplo de trabajo de los web workers Angular aquí

    webworker.controller('webWorkerCtrl', ['$scope', '$q', function($scope, $q) {
    
        $scope.workerReplyUI;
        $scope.callWebWorker = function() {
            var worker = new Worker('worker.js');
            var defer = $q.defer();
            worker.onmessage = function(e) {
                defer.resolve(e.data);
                worker.terminate();
            };
    
            worker.postMessage("http://jsonplaceholder.typicode.com/users");
            return defer.promise;
        }
    
        $scope.callWebWorker().then(function(workerReply) {
            $scope.workerReplyUI = workerReply;
        });
    
    }]);

    Utiliza promesas que esperar para el trabajador para devolver el resultado.

    El sitio que aloja el ejemplo no está disponible. Aquí está el enlace con el archivo web.archive.org/web/20150709233911/http://…

    OriginalEl autor Octane

  4. 7

    Angular Web Trabajador de la votación ejemplo

    Cuando se trata de lidiar con los trabajadores en AngularJS a menudo es necesario que el trabajador de la secuencia de comandos en línea(en caso que usted está usando alguna de las herramientas de generación como gulp/grunt) y podemos conseguirlo mediante el siguiente enfoque.

    Ejemplo siguiente muestra también cómo la votación se puede hacer con el servidor usando los trabajadores:

    En primer lugar vamos a crear nuestro trabajador de la fábrica:

        module.factory("myWorker", function($q) {
    var worker = undefined;
    return {
    startWork: function(postData) {
    var defer = $q.defer();
    if (worker) {
    worker.terminate();
    }
    //function to be your worker
    function workerFunction() {
    var self = this;
    self.onmessage = function(event) {
    var timeoutPromise = undefined;
    var dataUrl = event.data.dataUrl;
    var pollingInterval = event.data.pollingInterval;
    if (dataUrl) {
    if (timeoutPromise) {
    setTimeout.cancel(timeoutPromise); //cancelling previous promises
    }
    console.log('Notifications - Data URL: ' + dataUrl);
    //get Notification count
    var delay = 5000; //poller 5sec delay
    (function pollerFunc() {
    timeoutPromise = setTimeout(function() {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
    var response = JSON.parse(xmlhttp.responseText);
    self.postMessage(response.id);
    pollerFunc();
    }
    };
    xmlhttp.open('GET', dataUrl, true);
    xmlhttp.send();
    }, delay);
    })();
    }
    }
    }
    //end worker function
    var dataObj = '(' + workerFunction + ')();'; //here is the trick to convert the above fucntion to string
    var blob = new Blob([dataObj.replace('"use strict";', '')]); //firefox adds user strict to any function which was blocking might block worker execution so knock it off
    var blobURL = (window.URL ? URL : webkitURL).createObjectURL(blob, {
    type: 'application/javascript; charset=utf-8'
    });
    worker = new Worker(blobURL);
    worker.onmessage = function(e) {
    console.log('Worker said: ', e.data);
    defer.notify(e.data);
    };
    worker.postMessage(postData); //Send data to our worker.
    return defer.promise;
    },
    stopWork: function() {
    if (worker) {
    worker.terminate();
    }
    }
    }
    });

    Siguiente de nuestro controlador llame al trabajador de la fábrica:

    var inputToWorker = {
    dataUrl: "http://jsonplaceholder.typicode.com/posts/1", //url to poll
    pollingInterval: 5 //interval
    };
    myWorker.startWork(inputToWorker).then(function(response) {
    //complete
    }, function(error) {
    //error
    }, function(response) {
    //notify (here you receive intermittent responses from worker)
    console.log("Notification worker RESPONSE: " + response);
    });

    Puede llamar myWorker.stopWork(); cualquier momento para cancelar el trabajador de su controlador!

    Esto es probado en IE11+ y FF y Chrome

    este no está siendo invocado. Y de haber perdido la pollingInterval no utilizar en cualquier lugar.

    OriginalEl autor Chanakya Vadla

  5. 2

    también puede echar un vistazo a angular plugin https://github.com/vkiryukhin/ng-vkthread

    que permite ejecutar una función en un hilo separado.
    uso básico:

    /* function to execute in a thread */
    function foo(n, m){ 
    return n + m;
    }
    /* create an object, which you pass to vkThread as an argument*/
    var param = {
    fn: foo      //<-- function to execute
    args: [1, 2] //<-- arguments for this function
    };
    /* run thread */
    vkThread.exec(param).then(
    function (data) {
    console.log(data);  //<-- thread returns 3 
    }
    );

    Ejemplos y API doc: http://www.eslinstructor.net/ng-vkthread/demo/

    –Vadim

    esto es impresionante!!

    OriginalEl autor vadimk

Dejar respuesta

Please enter your comment!
Please enter your name here