una tablas tabla obtener objetos hacer filas editar dinamicas datos con array agregar javascript web-worker data-uri

javascript - tablas - Cómo crear un trabajador web a partir de una cadena



obtener datos de una tabla html javascript (8)

Resumen

  • blob: para Chrome 8+, Firefox 6+, Safari 6.0+, Opera 15+
  • data:application/javascript para Opera 10.60 - 12
  • eval contrario (IE 10+)

URL.createObjectURL(<Blob blob>) se puede usar para crear un trabajador web a partir de una cadena. El blob se puede crear usando la API BlobBuilder desuso o el constructor Blob .

Demostración: http://jsfiddle.net/uqcFM/49/

// URL.createObjectURL window.URL = window.URL || window.webkitURL; // "Server response", used in all examples var response = "self.onmessage=function(e){postMessage(''Worker: ''+e.data);}"; var blob; try { blob = new Blob([response], {type: ''application/javascript''}); } catch (e) { // Backwards-compatibility window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; blob = new BlobBuilder(); blob.append(response); blob = blob.getBlob(); } var worker = new Worker(URL.createObjectURL(blob)); // Test, used in all examples: worker.onmessage = function(e) { alert(''Response: '' + e.data); }; worker.postMessage(''Test'');

Compatibilidad

Los trabajadores web son compatibles en la siguiente source navegadores:

  • Chrome 3
  • Firefox 3.5
  • IE 10
  • Opera 10.60
  • Safari 4

El soporte de este método se basa en el soporte de la API Blob y el método URL.createObjectUrl . Compatibilidad Blob :

  • Chrome 8+ ( WebKitBlobBuilder ), 20+ (constructor Blob )
  • Firefox 6+ ( MozBlobBuilder ), 13+ (constructor Blob )
  • Safari 6+ (constructor Blob )

IE10 es compatible con MSBlobBuilder y URL.createObjectURL . Sin embargo, al tratar de crear un Trabajador web a partir de un blob: -URL arroja un SecurityError.

Opera 12 no es compatible con API de URL . Algunos usuarios pueden tener una versión falsa del objeto URL , gracias a este truco en browser.js .

Fallback 1: URI de datos

Opera admite URI de datos como argumento para el constructor Worker . Nota: No olvides escapar caracteres especiales (como # y % ).

// response as defined in the first example var worker = new Worker(''data:application/javascript,'' + encodeURIComponent(response) ); // ... Test as defined in the first example

Demostración: http://jsfiddle.net/uqcFM/37/

Fallback 2: Evaluar

eval se puede usar como respaldo para Safari (<6) e IE 10.

// Worker-helper.js self.onmessage = function(e) { self.onmessage = null; // Clean-up eval(e.data); }; // Usage: var worker = new Worker(''Worker-helper.js''); // `response` as defined in the first example worker.postMessage(response); // .. Test as defined in the first example

¿Cómo puedo usar crear un trabajador web a partir de una cadena (que se proporciona a través de una solicitud POST)?

Una forma en que puedo pensar, pero no estoy seguro de cómo implementarlo, es creando un URI de datos a partir de la respuesta del servidor, y pasándolo al constructor Worker, pero he oído que algunos navegadores no permiten esto, debido a la misma política de origen.

MDN declara la incertidumbre sobre la política de origen en torno a los URI de datos :

Nota: El URI pasado como parámetro del constructor Worker debe obedecer a la política del mismo origen. Actualmente existe un desacuerdo entre los proveedores de navegadores sobre si los URI de datos son del mismo origen o no; Gecko 10.0 (Firefox 10.0 / Thunderbird 10.0) y luego permite URI de datos como un script válido para los trabajadores. Otros navegadores pueden estar en desacuerdo.

Aquí también hay una publicación discutiéndolo en el whatwg .


Ampliando el código de @ Chanu_Sukarno, simplemente puede pasar una función de trabajador (o cadena) a esta función y la ejecutará dentro de un trabajador web:

async function doWorkerTask(workerFunction, input, buffers) { // Create worker let fnString = ''('' + workerFunction.toString().replace(''"use strict";'', '''') + '')();''; let workerBlob = new Blob([fnString]); let workerBlobURL = window.URL.createObjectURL(workerBlob, { type: ''application/javascript; charset=utf-8'' }); let worker = new Worker(workerBlobURL); // Run worker return await new Promise(function(resolve, reject) { worker.onmessage = function(e) { resolve(e.data); }; worker.postMessage(input, buffers); }); }

Aquí hay un ejemplo de cómo usarlo:

function myTask() { self.onmessage = function(e) { // do stuff with `e.data`, then: self.postMessage("my response"); self.close(); } } let output = await doWorkerTask(myTask, input, inputBuffers); // now you can do something with `output` (which will be equal to "my response")

En nodejs , doWorkerTask ve así:

async function doWorkerTask(workerFunction, input, buffers) { let Worker = require(''webworker-threads'').Worker; let worker = new Worker(workerFunction); // Run worker return await new Promise(function(resolve, reject) { worker.onmessage = function(e) { resolve(e.data); }; worker.postMessage(input, buffers); }); }


Buena respuesta: he estado trabajando en un problema similar hoy cuando trato de crear Web Workers con capacidades de respaldo cuando no están disponibles (es decir, ejecutar script de trabajador en el hilo principal). Como este hilo pertenece al tema, pensé que proporcionaría mi solución aquí:

<script type="javascript/worker"> //WORKER FUNCTIONS self.onmessage = function(event) { postMessage(''Hello, '' + event.data.name + ''!''); } </script> <script type="text/javascript"> function inlineWorker(parts, params, callback) { var URL = (window.URL || window.webkitURL); if (!URL && window.Worker) { var worker = new window.Worker(URL.createObjectURL(new Blob([parts], { "type" : "text/javascript" }))); worker.onmessage = function(event) { callback(event.data); }; worker.postMessage(params); } else { var postMessage = function(result) { callback(result); }; var self = {}; //''self'' in scope of inlineWorker. eval(parts); //Converts self.onmessage function string to function on self via nearest scope (previous line) - please email [email protected] if this could be tidier. self.onmessage({ data: params }); } } inlineWorker( document.querySelector(''[type="javascript/worker"]'').textContent, { name: ''Chaps!!'' }, function(result) { document.body.innerHTML = result; } ); </script> </body>


Dependiendo de su caso de uso, puede usar algo como

task.js Interfaz simplificada para hacer que el código intensivo de la CPU se ejecute en todos los núcleos (node.js y web)

Un ejemplo sería

// turn blocking pure function into a worker task const functionFromPostRequest = task.wrap(''function (exampleArgument) {}''); // run task on a autoscaling worker pool functionFromPostRequest(''exampleArgumentValue'').then(result => { // do something with result });


Estoy de acuerdo con la respuesta aceptada actual, pero a menudo la edición y la administración del código de trabajador serán agitadas ya que se trata de una cadena.

Entonces, opcionalmente, podemos usar el siguiente enfoque donde podemos mantener al trabajador como una función, y luego convertirlo a string-> blob:

// function to be your worker function workerFunction() { var self = this; self.onmessage = function(e) { console.log(''Received input: '', e.data); // message received from main thread self.postMessage("Response back to main thread"); } } /////////////////////////////// var dataObj = ''('' + workerFunction + '')();''; // here is the trick to convert the above fucntion to string var blob = new Blob([dataObj.replace(''"use strict";'', '''')]); // firefox adds "use strict"; to any function which might block worker execution so knock it off var blobURL = (window.URL ? URL : webkitURL).createObjectURL(blob, { type: ''application/javascript; charset=utf-8'' }); var worker = new Worker(blobURL); // spawn new worker worker.onmessage = function(e) { console.log(''Worker said: '', e.data); // message received from worker }; worker.postMessage("some input to worker"); // Send data to our worker.

Esto se prueba en IE11 + y FF y Chrome


Formulé un enfoque con la mayoría de sus ideas y agregué algunas de las mías. Lo único que mi código necesita del trabajador es usar ''esto'' para referirse al ''alcance propio''. Estoy bastante seguro de que esto es muy mejorable:

// Sample code var code = function() { this.onmessage = function(e) { this.postMessage(''Worker: ''+e.data); this.postMessage(''Worker2: ''+e.data); }; }; // New thread worker code FakeWorkerCode = function(code, worker) { code.call(this); this.worker = worker; } FakeWorkerCode.prototype.postMessage = function(e) { this.worker.onmessage({data: e}); } // Main thread worker side FakeWorker = function(code) { this.code = new FakeWorkerCode(code, this); } FakeWorker.prototype.postMessage = function(e) { this.code.onmessage({data: e}); } // Utilities for generating workers Utils = { stringifyFunction: function(func) { // Stringify the code return ''('' + func + '').call(self);''; }, generateWorker: function(code) { // URL.createObjectURL windowURL = window.URL || window.webkitURL; var blob, worker; var stringified = Utils.stringifyFunction(code); try { blob = new Blob([stringified], {type: ''application/javascript''}); } catch (e) { // Backwards-compatibility window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; blob = new BlobBuilder(); blob.append(stringified); blob = blob.getBlob(); } if ("Worker" in window) { worker = new Worker(windowURL.createObjectURL(blob)); } else { worker = new FakeWorker(code); } return worker; } }; // Generate worker var worker = Utils.generateWorker(code); // Test, used in all examples: worker.onmessage = function(e) { alert(''Response: '' + e.data); }; function runWorker() { worker.postMessage(''working fine''); }

Demostración: http://jsfiddle.net/8N6aR/


Puede obtener datos reales de objectURL y no solo blob cambiando el tipo de responseType a "text" o "arraybuffer" .

Aquí hay una conversión ida y vuelta de text/javascript a blob a objectURL a blob o text/javascript .

si se lo está preguntando, lo estoy usando para generar un trabajador web sin archivos externos
puede usarlo para devolver contenido binario, por ejemplo, un video de YouTube;) (del atributo de recurso de etiqueta <video>)

var blob = new Blob([''self.onmessage=function(e){postMessage(e)}''],{type: ''text/javascript''}); //->console: (object) Blob {size: 42, type: "text/javascript", slice: function} var obju = URL.createObjectURL(js_blob); //->console: "blob:http%3A//.com/02e79c2b-025a-4293-be0f-f121dd57ccf7" var xhr = new XMLHttpRequest(); xhr.open(''GET'', ''blob:http%3A//.com/02e79c2b-025a-4293-be0f-f121dd57ccf7'', true); xhr.responseType = ''text''; /* or "blob" */ xhr.onreadystatechange = function(){ if(xhr.DONE !== xhr.readyState) return; console.log(xhr.response); } xhr.send(); /* responseType "blob" ->console: (object) Blob {size: 42, type: "text/javascript", slice: function} responseType "text" ->console: (text) ''self.onmessage=function(e){postMessage(e)}'' */


Use mi pequeño complemento https://github.com/zevero/worker-create

var worker_url = Worker.create("self.postMessage(''Example post from Worker'');"); var worker = new Worker(worker_url);

Pero también puedes darle una función.