Run a Script Agains a Web Page
Using Web Workers
Spider web Workers are a uncomplicated means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface. In addition, they can perform I/O using XMLHttpRequest (although the responseXML and channel attributes are ever null) or fetch (with no such restrictions). Once created, a worker can send letters to the JavaScript code that created it by posting messages to an event handler specified by that code (and vice versa).
This commodity provides a detailed introduction to using web workers.
Web Workers API
A worker is an object created using a constructor (e.g. Worker()) that runs a named JavaScript file — this file contains the code that volition run in the worker thread; workers run in some other global context that is different from the current window. Thus, using the window shortcut to go the current global scope (instead of self) within a Worker volition render an error.
The worker context is represented by a DedicatedWorkerGlobalScope object in the case of dedicated workers (standard workers that are utilized by a unmarried script; shared workers use SharedWorkerGlobalScope). A dedicated worker is only attainable from the script that outset spawned it, whereas shared workers can be accessed from multiple scripts.
You lot tin can run whatever lawmaking you like inside the worker thread, with some exceptions. For case, yous can't directly manipulate the DOM from inside a worker, or utilize some default methods and properties of the window object. But yous can use a big number of items available nether window, including WebSockets, and data storage mechanisms like IndexedDB. See Functions and classes available to workers for more details.
Data is sent between workers and the main thread via a organisation of messages — both sides send their messages using the postMessage() method, and answer to letters via the onmessage consequence handler (the message is independent within the Message event's data attribute.) The information is copied rather than shared.
Workers may, in turn, spawn new workers, equally long as those workers are hosted within the same origin as the parent page. In improver, workers may use XMLHttpRequest for network I/O, with the exception that the responseXML and channel attributes on XMLHttpRequest always return zero.
Dedicated workers
As mentioned above, a dedicated worker is only attainable by the script that called it. In this department nosotros'll discuss the JavaScript found in our Basic dedicated worker example (run dedicated worker): This allows you to enter 2 numbers to be multiplied together. The numbers are sent to a defended worker, multiplied together, and the result is returned to the page and displayed.
This example is rather trivial, only we decided to keep it uncomplicated while introducing yous to basic worker concepts. More than advanced details are covered later on in the commodity.
Worker feature detection
For slightly more than controlled error handling and backwards compatibility, it is a good idea to wrap your worker accessing lawmaking in the following (principal.js):
if (window.Worker) { ... } Spawning a dedicated worker
Creating a new worker is simple. All you demand to practice is call the Worker() constructor, specifying the URI of a script to execute in the worker thread (main.js):
var myWorker = new Worker ( 'worker.js' ) ; Sending messages to and from a dedicated worker
The magic of workers happens via the postMessage() method and the onmessage effect handler. When you desire to ship a message to the worker, yous post messages to information technology like this (main.js):
first. onchange = function ( ) { myWorker. postMessage ( [first.value, second.value] ) ; console. log ( 'Message posted to worker' ) ; } second. onchange = function ( ) { myWorker. postMessage ( [first.value, 2d.value] ) ; console. log ( 'Bulletin posted to worker' ) ; } And so hither we accept two <input> elements represented past the variables first and second; when the value of either is inverse, myWorker.postMessage([first.value,second.value]) is used to transport the value within both to the worker, every bit an array. Yous can transport pretty much annihilation you lot like in the bulletin.
In the worker, we can reply when the message is received past writing an event handler block like this (worker.js):
onmessage = office ( due east ) { console. log ( 'Bulletin received from principal script' ) ; var workerResult = 'Result: ' + (east.data[ 0 ] * e.information[ one ] ) ; console. log ( 'Posting message back to principal script' ) ; postMessage (workerResult) ; } The onmessage handler allows usa to run some code whenever a message is received, with the bulletin itself being bachelor in the message event's information attribute. Here we multiply together the 2 numbers then use postMessage() again, to postal service the consequence back to the main thread.
Back in the main thread, we employ onmessage again, to answer to the message sent back from the worker:
myWorker. onmessage = office ( east ) { result.textContent = e.data; console. log ( 'Message received from worker' ) ; } Here we catch the bulletin event information and set it as the textContent of the result paragraph, then the user can see the result of the adding.
Note: Observe that onmessage and postMessage() need to be hung off the Worker object when used in the principal script thread, just not when used in the worker. This is because, inside the worker, the worker is effectively the global telescopic.
Note: When a bulletin is passed between the principal thread and worker, information technology is copied or "transferred" (moved), not shared. Read Transferring data to and from workers: farther details for a much more thorough explanation.
Terminating a worker
If you need to immediately terminate a running worker from the main thread, you lot can exercise so by calling the worker's cease method:
The worker thread is killed immediately.
Handling errors
When a runtime error occurs in the worker, its onerror event handler is chosen. It receives an event named error which implements the ErrorEvent interface.
The consequence doesn't bubble and is cancelable; to prevent the default action from taking identify, the worker can telephone call the error effect's preventDefault() method.
The error result has the post-obit three fields that are of interest:
-
bulletin -
A human-readable fault message.
-
filename -
The name of the script file in which the error occurred.
-
lineno -
The line number of the script file on which the error occurred.
Spawning subworkers
Workers may spawn more workers if they wish. And so-called sub-workers must be hosted within the same origin as the parent page. Also, the URIs for subworkers are resolved relative to the parent worker'due south location rather than that of the owning folio. This makes it easier for workers to go along track of where their dependencies are.
Importing scripts and libraries
Worker threads accept access to a global function, importScripts(), which lets them import scripts. It accepts zero or more URIs every bit parameters to resource to import; all of the following examples are valid:
importScripts ( ) ; /* imports zippo */ importScripts ( 'foo.js' ) ; /* imports just "foo.js" */ importScripts ( 'foo.js' , 'bar.js' ) ; /* imports two scripts */ importScripts ( '//example.com/hello.js' ) ; /* You can import scripts from other origins */ The browser loads each listed script and executes it. Any global objects from each script may so be used past the worker. If the script can't exist loaded, NETWORK_ERROR is thrown, and subsequent code will not be executed. Previously executed code (including code deferred using setTimeout()) will notwithstanding be functional though. Part declarations afterward the importScripts() method are also kept, since these are ever evaluated before the rest of the code.
Notation: Scripts may exist downloaded in any order, but will be executed in the social club in which y'all pass the filenames into importScripts() . This is washed synchronously; importScripts() does non render until all the scripts have been loaded and executed.
A shared worker is accessible by multiple scripts — even if they are beingness accessed by different windows, iframes or even workers. In this department we'll discuss the JavaScript constitute in our Basic shared worker example (run shared worker): This is very like to the bones defended worker instance, except that information technology has ii functions bachelor handled by different script files: multiplying ii numbers, or squaring a number. Both scripts use the same worker to exercise the actual calculation required.
Here we'll concentrate on the differences between defended and shared workers. Note that in this example nosotros have two HTML pages, each with JavaScript applied that uses the same unmarried worker file.
Note: If SharedWorker tin can be accessed from several browsing contexts, all those browsing contexts must share the exact same origin (aforementioned protocol, host, and port).
Note: In Firefox, shared workers cannot be shared between documents loaded in private and non-private windows (problems 1177621).
Spawning a shared worker
Spawning a new shared worker is pretty much the aforementioned every bit with a defended worker, but with a different constructor proper name (run across alphabetize.html and index2.html) — each one has to spin up the worker using lawmaking like the post-obit:
var myWorker = new SharedWorker ( 'worker.js' ) ; One big difference is that with a shared worker you take to communicate via a port object — an explicit port is opened that the scripts can employ to communicate with the worker (this is washed implicitly in the example of dedicated workers).
The port connection needs to be started either implicitly by use of the onmessage event handler or explicitly with the beginning() method before any messages can be posted. Calling start() is only needed if the message event is wired upward via the addEventListener() method.
Note: When using the start() method to open the port connexion, it needs to be called from both the parent thread and the worker thread if two-style communication is needed.
Sending letters to and from a shared worker
Now messages tin can be sent to the worker as before, but the postMessage() method has to be invoked through the port object (again, you'll encounter similar constructs in both multiply.js and square.js):
squareNumber. onchange = function ( ) { myWorker.port. postMessage ( [squareNumber.value,squareNumber.value] ) ; console. log ( 'Bulletin posted to worker' ) ; } Now, on to the worker. There is a flake more complication here equally well (worker.js):
onconnect = function ( eastward ) { var port = east.ports[ 0 ] ; port. onmessage = part ( e ) { var workerResult = 'Outcome: ' + (eastward.data[ 0 ] * eastward.data[ 1 ] ) ; port. postMessage (workerResult) ; } } First, nosotros use an onconnect handler to fire lawmaking when a connection to the port happens (i.e. when the onmessage event handler in the parent thread is setup, or when the showtime() method is explicitly called in the parent thread).
We use the ports attribute of this event object to catch the port and store it in a variable.
Adjacent, we add a message handler on the port to practice the calculation and return the result to the principal thread. Setting up this message handler in the worker thread also implicitly opens the port connection back to the parent thread, then the call to port.outset() is not really needed, as noted higher up.
Finally, dorsum in the main script, we bargain with the message (again, you'll see similar constructs in both multiply.js and square.js):
myWorker.port. onmessage = role ( e ) { result2.textContent = e.data; panel. log ( 'Message received from worker' ) ; } When a bulletin comes back through the port from the worker, we insert the calculation outcome inside the advisable result paragraph.
Most thread safety
The Worker interface spawns real Os-level threads, and mindful programmers may be concerned that concurrency tin can cause "interesting" effects in your lawmaking if you aren't careful.
However, since web workers accept carefully controlled communication points with other threads, information technology'southward really very hard to cause concurrency problems. At that place'south no access to non-threadsafe components or the DOM. And yous take to pass specific data in and out of a thread through serialized objects. Then you have to work really hard to cause problems in your lawmaking.
Content security policy
Workers are considered to have their own execution context, distinct from the certificate that created them. For this reason they are, in general, not governed past the content security policy of the document (or parent worker) that created them. So for case, suppose a document is served with the following header:
Content-Security-Policy: script-src 'cocky'
Amidst other things, this volition preclude any scripts it includes from using eval(). Even so, if the script constructs a worker, code running in the worker's context volition be allowed to utilize eval().
To specify a content security policy for the worker, set a Content-Security-Policy response header for the request which delivered the worker script itself.
The exception to this is if the worker script'due south origin is a globally unique identifier (for example, if its URL has a scheme of data or blob). In this case, the worker does inherit the CSP of the document or worker that created it.
Transferring data to and from workers: further details
Data passed between the master page and workers is copied, not shared. Objects are serialized as they're handed to the worker, and subsequently, de-serialized on the other terminate. The page and worker exercise non share the same case, and then the finish result is that a duplicate is created on each cease. Well-nigh browsers implement this feature as structured cloning.
To illustrate this, allow's create a function named emulateMessage(), which will simulate the behavior of a value that is cloned and non shared during the passage from a worker to the main page or vice versa:
function emulateMessage ( vVal ) { return eval ( '(' + JSON . stringify (vVal) + ')' ) ; } // Tests // test #one var example1 = new Number ( 3 ) ; panel. log ( typeof example1) ; // object panel. log ( typeof emulateMessage (example1) ) ; // number // exam #2 var example2 = truthful ; console. log ( typeof example2) ; // boolean console. log ( typeof emulateMessage (example2) ) ; // boolean // test #iii var example3 = new String ( 'Howdy Globe' ) ; console. log ( typeof example3) ; // object console. log ( typeof emulateMessage (example3) ) ; // cord // test #4 var example4 = { 'proper name' : 'John Smith' , "age" : 43 } ; console. log ( typeof example4) ; // object panel. log ( typeof emulateMessage (example4) ) ; // object // exam #5 function Animal ( sType, nAge ) { this .type = sType; this .age = nAge; } var example5 = new Animal ( 'Cat' , 3 ) ; warning (example5.constructor) ; // Animal alert ( emulateMessage (example5) .constructor) ; // Object A value that is cloned and non shared is called bulletin. As you will probably know by now, messages tin exist sent to and from the main thread by using postMessage(), and the bulletin event's data attribute contains data passed back from the worker.
example.html: (the main page):
var myWorker = new Worker ( 'my_task.js' ) ; myWorker. onmessage = office ( oEvent ) { console. log ( 'Worker said : ' + oEvent.data) ; } ; myWorker. postMessage ( 'ali' ) ; my_task.js (the worker):
postMessage ( "I\'m working before postMessage(\'ali\')." ) ; onmessage = function ( oEvent ) { postMessage ( 'Hi ' + oEvent.data) ; } ; The structured cloning algorithm can take JSON and a few things that JSON tin can't — like circular references.
Passing data examples
Example #1: Advanced passing JSON Data and creating a switching organization
If you lot accept to pass some circuitous data and have to call many unlike functions both on the main page and in the Worker, yous can create a arrangement which groups everything together.
First, nosotros create a QueryableWorker grade that takes the URL of the worker, a default listener, and an error handler, and this class is going to go along track of a listing of listeners and help united states communicate with the worker:
part QueryableWorker ( url, defaultListener, onError ) { var case = this , worker = new Worker (url) , listeners = { } ; this .defaultListener = defaultListener || part ( ) { } ; if (onError) {worker.onerror = onError; } this . postMessage = function ( message ) { worker. postMessage (message) ; } this . cease = function ( ) { worker. terminate ( ) ; } } Then we add the methods of adding/removing listeners:
this . addListeners = function ( proper noun, listener ) { listeners[name] = listener; } this . removeListeners = office ( proper noun ) { delete listeners[name] ; } Here we allow the worker handle ii simple operations for illustration: getting the difference of two numbers and making an alert after three seconds. In order to reach that nosotros first implement a sendQuery method which queries if the worker actually has the corresponding methods to practice what we want.
/* This functions takes at to the lowest degree one argument, the method name we want to query. So nosotros tin pass in the arguments that the method needs. */ this . sendQuery = office ( ) { if (arguments.length < 1 ) { throw new TypeError ( 'QueryableWorker.sendQuery takes at least one argument' ) ; return ; } worker. postMessage ( { 'queryMethod' : arguments[ 0 ] , 'queryMethodArguments' : Array .prototype. slice . telephone call (arguments, i ) } ) ; } We cease QueryableWorker with the onmessage method. If the worker has the corresponding methods nosotros queried, it should render the name of the corresponding listener and the arguments it needs, we but need to find it in listeners.:
worker. onmessage = part ( issue ) { if (result.information instanceof Object && event.data. hasOwnProperty ( 'queryMethodListener' ) && event.information. hasOwnProperty ( 'queryMethodArguments' ) ) { listeners[event.data.queryMethodListener] . apply (instance, event.data.queryMethodArguments) ; } else { this . defaultListener . telephone call (instance, event.data) ; } } At present onto the worker. Showtime we need to have the methods to handle the 2 elementary operations:
var queryableFunctions = { getDifference : part ( a, b ) { reply ( 'printStuff' , a - b) ; } , waitSomeTime : function ( ) { setTimeout ( function ( ) { respond ( 'doAlert' , 3 , 'seconds' ) ; } , 3000 ) ; } } part answer ( ) { if (arguments.length < 1 ) { throw new TypeError ( 'reply - takes at least one statement' ) ; return ; } postMessage ( { queryMethodListener : arguments[ 0 ] , queryMethodArguments : Array .prototype. slice . call (arguments, 1 ) } ) ; } /* This method is chosen when primary page calls QueryWorker's postMessage method directly*/ function defaultReply ( bulletin ) { // do something } And the onmessage method is now lilliputian:
onmessage = function ( event ) { if (upshot.data instanceof Object && event.information. hasOwnProperty ( 'queryMethod' ) && result.data. hasOwnProperty ( 'queryMethodArguments' ) ) { queryableFunctions[event.data.queryMethod] . apply (self, event.data.queryMethodArguments) ; } else { defaultReply (event.data) ; } } Here are the full implementation:
example.html (the chief page):
<! doctype html > <html > <head > <meta charset = "UTF-8" /> <championship > MDN Example - Queryable worker </championship > <script type = "text/javascript" > /* QueryableWorker instances methods: * sendQuery(queryable function proper name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker'southward queryable function * postMessage(cord or JSON Data): meet Worker.prototype.postMessage() * finish(): terminates the Worker * addListener(name, office): adds a listener * removeListener(name): removes a listener QueryableWorker instances properties: * defaultListener: the default listener executed only when the Worker calls the postMessage() role directly */ function QueryableWorker ( url, defaultListener, onError ) { var instance = this , worker = new Worker (url) , listeners = { } ; this .defaultListener = defaultListener || role ( ) { } ; if (onError) {worker.onerror = onError; } this . postMessage = function ( bulletin ) { worker. postMessage (bulletin) ; } this . terminate = function ( ) { worker. stop ( ) ; } this . addListener = function ( name, listener ) { listeners[proper noun] = listener; } this . removeListener = function ( name ) { delete listeners[name] ; } /* This functions takes at to the lowest degree 1 argument, the method name we want to query. Then we tin laissez passer in the arguments that the method needs. */ this . sendQuery = function ( ) { if (arguments.length < one ) { throw new TypeError ( 'QueryableWorker.sendQuery takes at least one argument' ) ; return ; } worker. postMessage ( { 'queryMethod' : arguments[ 0 ] , 'queryMethodArguments' : Array .paradigm. slice . phone call (arguments, ane ) } ) ; } worker. onmessage = part ( event ) { if (event.information instanceof Object && event.data. hasOwnProperty ( 'queryMethodListener' ) && event.data. hasOwnProperty ( 'queryMethodArguments' ) ) { listeners[event.data.queryMethodListener] . employ (instance, effect.data.queryMethodArguments) ; } else { this . defaultListener . call (instance, consequence.data) ; } } } // your custom "queryable" worker var myTask = new QueryableWorker ( 'my_task.js' ) ; // your custom "listeners" myTask. addListener ( 'printStuff' , role ( result ) { document. getElementById ( 'firstLink' ) .parentNode. appendChild (document. createTextNode ( 'The deviation is ' + result + '!' ) ) ; } ) ; myTask. addListener ( 'doAlert' , role ( fourth dimension, unit ) { alert ( 'Worker waited for ' + fourth dimension + ' ' + unit + ' :-)' ) ; } ) ; </script > </head > <trunk > <ul > <li > <a id = "firstLink" href = "javascript:myTask.sendQuery('getDifference', 5, three);" > What is the deviation betwixt 5 and three? </a > </li > <li > <a href = "javascript:myTask.sendQuery('waitSomeTime');" > Wait iii seconds </a > </li > <li > <a href = "javascript:myTask.finish();" > terminate() the Worker </a > </li > </ul > </body > </html > my_task.js (the worker):
var queryableFunctions = { // example #1: get the deviation between two numbers: getDifference : part ( nMinuend, nSubtrahend ) { reply ( 'printStuff' , nMinuend - nSubtrahend) ; } , // example #2: wait 3 seconds waitSomeTime : function ( ) { setTimeout ( office ( ) { reply ( 'doAlert' , iii , 'seconds' ) ; } , 3000 ) ; } } ; // organisation functions office defaultReply ( message ) { // your default PUBLIC function executed just when master page calls the queryableWorker.postMessage() method directly // do something } office answer ( ) { if (arguments.length < 1 ) { throw new TypeError ( 'reply - not enough arguments' ) ; return ; } postMessage ( { 'queryMethodListener' : arguments[ 0 ] , 'queryMethodArguments' : Array .prototype. piece . call (arguments, 1 ) } ) ; } onmessage = function ( oEvent ) { if (oEvent.data instanceof Object && oEvent.data. hasOwnProperty ( 'queryMethod' ) && oEvent.data. hasOwnProperty ( 'queryMethodArguments' ) ) { queryableFunctions[oEvent.data.queryMethod] . apply (cocky, oEvent.data.queryMethodArguments) ; } else { defaultReply (oEvent.data) ; } } ; It is possible to switch the content of each mainpage -> worker and worker -> mainpage message. And the property names "queryMethod", "queryMethodListeners", "queryMethodArguments" can be anything equally long as they are consequent in QueryableWorker and the worker.
Passing information by transferring ownership (transferable objects)
Modernistic browsers contain an additional manner to pass certain types of objects to or from a worker with loftier performance. Transferable Objects are transferred from one context to another with a cypher-copy functioning, which results in a vast performance improvement when sending large information sets.
For example, when transferring an ArrayBuffer from your chief app to a worker script, the original ArrayBuffer is cleared and no longer usable. Its content is (quite literally) transferred to the worker context.
// Create a 32MB "file" and fill it. var uInt8Array = new Uint8Array ( 1024 * 1024 * 32 ) ; // 32MB for ( var i = 0 ; i < uInt8Array.length; ++i) { uInt8Array[i] = i; } worker. postMessage (uInt8Array.buffer, [uInt8Array.buffer] ) ; Embedded workers
In that location is not an "official" manner to embed the code of a worker inside a spider web page, like <script> elements do for normal scripts. But a <script> element that does not have a src attribute and has a type attribute that does not identify an executable MIME type tin can be considered a information block element that JavaScript could employ. "Information blocks" is a more full general feature of HTML5 that can carry almost any textual data. And so, a worker could exist embedded in this manner:
<! DOCTYPE html > <html > <head > <meta charset = "UTF-8" /> <title > MDN Instance - Embedded worker </title > <script blazon = "text/js-worker" > // This script WON'T be parsed by JS engines because its MIME type is text/js-worker. var myVar = 'Hi World!' ; // Rest of your worker code goes here. </script > <script type = "text/javascript" > // This script Volition be parsed by JS engines considering its MIME blazon is text/javascript. function pageLog ( sMsg ) { // Utilise a fragment: browser will only render/reflow once. var oFragm = document. createDocumentFragment ( ) ; oFragm. appendChild (document. createTextNode (sMsg) ) ; oFragm. appendChild (document. createElement ( 'br' ) ) ; document. querySelector ( '#logDisplay' ) . appendChild (oFragm) ; } </script > <script type = "text/js-worker" > // This script WON'T be parsed by JS engines because its MIME type is text/js-worker. onmessage = role ( oEvent ) { postMessage (myVar) ; } ; // Residue of your worker code goes here. </script > <script type = "text/javascript" > // This script Volition be parsed by JS engines because its MIME blazon is text/javascript. // In the past...: // blob builder existed // ...but at present we use Hulk...: var blob = new Blob ( Array .prototype. map . call (document. querySelectorAll ( 'script[type=\'text\/js-worker\']' ) , function ( oScript ) { render oScript.textContent; } ) , { blazon : 'text/javascript' } ) ; // Creating a new certificate.worker property containing all our "text/js-worker" scripts. document.worker = new Worker (window. URL . createObjectURL (hulk) ) ; document.worker. onmessage = function ( oEvent ) { pageLog ( 'Received: ' + oEvent.data) ; } ; // Start the worker. window. onload = function ( ) { document.worker. postMessage ( '' ) ; } ; </script > </head > <body > <div id = "logDisplay" > </div > </body > </html > The embedded worker is now nested into a new custom document.worker property.
It is too worth noting that yous can also catechumen a role into a Blob, then generate an object URL from that blob. For case:
function fn2workerURL ( fn ) { var blob = new Hulk ( [ '(' +fn. toString ( ) + ')()' ] , { blazon : 'text/javascript' } ) return URL . createObjectURL (blob) } Further examples
This section provides further examples of how to use spider web workers.
Performing computations in the background
Workers are mainly useful for allowing your code to perform processor-intensive calculations without blocking the user interface thread. In this example, a worker is used to calculate Fibonacci numbers.
The JavaScript lawmaking
The following JavaScript code is stored in the "fibonacci.js" file referenced by the HTML in the adjacent section.
self. onmessage = office ( due east ) { permit userNum = Number (due east.data) ; fibonacci (userNum) ; } function fibonacci ( num ) { permit a = 1 , b = 0 , temp; while (num >= 0 ) { temp = a; a = a + b; b = temp; num-- ; } cocky. postMessage (b) ; } The worker sets the property onmessage to a function which will receive messages sent when the worker object's postMessage() is called (note that this differs from defining a global variable of that name, or defining a function with that proper noun. var onmessage and function onmessage will define global properties with those names, but they will non register the office to receive messages sent by the spider web page that created the worker). This starts the recursion, spawning new copies of itself to handle each iteration of the calculation.
The HTML code
<! DOCTYPE html > <html > <head > <meta charset = "UTF-8" /> <title > Fibonacci number generator </title > <style > trunk { width : 500px; } div, p { margin-bottom : 20px; } </style > </head > <body > <grade > <div > <characterization for = "number" > Enter a number that is an alphabetize position in the fibonacci sequence to run across what number is in that position (east.thousand. enter 5 and you'll get a effect of 8 — fibonacci index position five is 8). </label > <input blazon = "number" id = "number" > </div > <div > <input type = "submit" > </div > </form > <p id = "result" > </p > <script linguistic communication = "javascript" > var form = document. querySelector ( 'form' ) ; var input = document. querySelector ( 'input[type="number"]' ) ; var result = certificate. querySelector ( 'p#outcome' ) ; var worker = new Worker ( 'fibonacci.js' ) ; worker. onmessage = function ( result ) { result.textContent = upshot.data; panel. log ( 'Got: ' + upshot.data + '\n' ) ; } ; worker. onerror = role ( error ) { console. log ( 'Worker error: ' + mistake.message + '\north' ) ; throw error; } ; course. onsubmit = office ( e ) { e. preventDefault ( ) ; worker. postMessage (input.value) ; input.value = '' ; } </script > </trunk > </html > The web page creates a div element with the ID result , which gets used to display the result, so spawns the worker. Later on spawning the worker, the onmessage handler is configured to display the results by setting the contents of the div element, and the onerror handler is set to log the mistake message to the devtools panel.
Finally, a message is sent to the worker to offset it.
Attempt this case alive.
Dividing tasks amid multiple workers
As multi-core computers become increasingly common, it'southward often useful to separate computationally circuitous tasks among multiple workers, which may then perform those tasks on multiple-processor cores.
Other types of worker
In addition to defended and shared web workers, there are other types of worker available:
- ServiceWorkers substantially deed as proxy servers that sit between web applications, and the browser and network (when available). They are intended to (amid other things) enable the cosmos of effective offline experiences, intercepting network requests and taking appropriate action based on whether the network is available and updated assets reside on the server. They will also permit access to push notifications and groundwork sync APIs.
- Audio Worklet provide the ability for direct scripted sound processing to be done in a worklet (a lightweight version of worker) context.
Debugging worker threads
Well-nigh browsers support debugging of worker threads in their JavaScript debuggers in exactly the same way as debugging the main thread! For example, both Firefox and Chrome list JavaScript source files for both the main thread and active worker threads, and all of these files tin can be opened to set breakpoints and logpoints.
The screenshot below shows this on Firefox. The sources list shows worker.js running in a separate worker thread. When selected this file is opened in the source pane, only like code running in the main thread.
Annotation: Worker scripts are loaded when needed, and hence may not be present in the sources list when a page is commencement loaded.
In the source pane you tin can set up a breakpoint (or logpoint) in a worker thread in the normal way. When execution is paused, the context of the debugger is updated to show correct breakpoints, inline variable preview, call stack, etc., just as y'all'd expect.
Functions and interfaces available in workers
You can utilize most standard JavaScript features inside a web worker, including:
-
Navigator -
XMLHttpRequest -
Array,Date,Math, andString -
setTimeout()andsetInterval()
The master thing yous tin can't do in a Worker is directly affect the parent page. This includes manipulating the DOM and using that page's objects. Yous have to exercise it indirectly, by sending a message back to the main script via DedicatedWorkerGlobalScope.postMessage, then actioning the changes from there.
Note: You can test whether a method is available to workers using the site: https://worker-playground.glitch.me/ . For example, if you enter EventSource into the site on Firefox 84 you'll see that this is not supported in service workers, only is in defended and shared workers.
Specifications
Meet too
campbellaunuentid.blogspot.com
Source: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
Postar um comentário for "Run a Script Agains a Web Page"