UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

173 lines (140 loc) 4.2 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2011 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Tino Butz (tbtz) * Adrian Olaru (adrianolaru) ************************************************************************ */ /** * EXPERIMENTAL - NOT READY FOR PRODUCTION * * Web Workers allows us to run JavaScript in parallel on a web page, * without blocking the user interface. A 'worker' is just another script * file that will be loaded and executed in the background. * * NOTE: Instances of this class must be disposed of after use * * For more information see: * http://www.w3.org/TR/workers/ */ qx.Class.define("qx.bom.WebWorker", { extend : qx.core.Object, implement: [ qx.core.IDisposable ], /** * Create a new instance. * * @param src {String} The path to worker as an URL */ construct: function(src) { this.base(arguments); this.__isNative = qx.core.Environment.get("html.webworker"); this.__isNative ? this.__initNative(src) : this.__initFake(src); }, events : { /** Fired when worker sends a message */ "message": "qx.event.type.Data", /** Fired when an error occurs */ "error": "qx.event.type.Data" }, members : { _worker : null, _handleErrorBound : null, _handleMessageBound : null, __isNative : true, __fake : null, /** * Initialize the native worker * @param src {String} The path to worker as an URL */ __initNative: function(src) { this._worker = new window.Worker(src); this._handleMessageBound = qx.lang.Function.bind(this._handleMessage, this); this._handleErrorBound = qx.lang.Function.bind(this._handleError, this); qx.bom.Event.addNativeListener(this._worker, "message", this._handleMessageBound); qx.bom.Event.addNativeListener(this._worker, "error", this._handleErrorBound); }, /** * Initialize the fake worker * @param src {String} The path to worker as an URL * @lint ignoreDeprecated(eval) */ __initFake: function(src) { var that = this; var req = new qx.bom.request.Xhr(); req.onload = function() { that.__fake = (function() { var postMessage = function(e) { that.fireDataEvent('message', e); }; //set up context vars before evaluating the code eval("var onmessage = null, postMessage = " + postMessage + ";" + req.responseText); //pick the right onmessage because of the uglyfier return { onmessage: eval("onmessage"), postMessage: postMessage }; })(); }; req.open("GET", src, false); req.send(); }, /** * Send a message to the worker. * @param msg {String} the message */ postMessage: function(msg) { var that = this; if (this.__isNative) { this._worker.postMessage(msg); } else { setTimeout(function() { try { that.__fake.onmessage && that.__fake.onmessage({data: msg}); } catch (ex) { that.fireDataEvent("error", ex); } }, 0); } }, /** * Message handler * @param e {Event} message event */ _handleMessage: function(e) { this.fireDataEvent("message", e.data); }, /** * Error handler * @param e {Event} error event */ _handleError: function(e) { this.fireDataEvent("error", e.message); } }, destruct : function() { if (this.__isNative) { qx.bom.Event.removeNativeListener(this._worker, "message", this._handleMessageBound); qx.bom.Event.removeNativeListener(this._worker, "error", this._handleErrorBound); if (this._worker) { this._worker.terminate(); this._worker = null; } } else { if (this.__fake) { this.__fake = null; } } } });