简体   繁体   中英

How are the web worker files loaded?

I want to emit something to the web-worker right after it was loaded. The code looks like:

var w = new Worker("worker.js");
w.onmessage = function (ev) {
    console.log(ev.data);
};
w.postMessage("Hello World");

In worker.js I have:

this.onmessage = function (ev) {
    self.postMessage(ev.data);
}

So, the event flow is like this:

window -- Hello World -> web worker -- Hello World -> window -> console.log(ev.data)

My question is why does this work? That means the worker.js file was loaded synchronously. Is that correct?

I even tried loading other files in the web worker:

importScripts('foo.js');
importScripts('bar.js');

Even loading these files work fine. Why? How are the web worker files loaded, from a low-level perspective?

new Worker("worker.js") does not “network-block” the calling thread (“main thread”). The new call returns independent of the state of the worker. The worker might not yet be done with executing its script, with loading its script, or even initializing itself to the state where it can start/order the loading of its script.

Your following onmessage is set up in the main thread independent of the worker state. That does not block either.

The postMessage() call will queue a message for the worker without waiting for its pickup. At this point the main thread is done executing (“fell through the bottom”) and its event loop will be waiting for events.

The worker runs independent of the main thread (well... that is the whole point of creating a worker). It will first run through its worker script. Right now I can't think of any way for it to (temporarily) yield execution, which means that the whole worker script needs to “fall through the bottom”, ie finish execution before the worker's individual event loop is given control (again).

Only then the message from the main thread will be picked up by Javascript when it runs the worker thread's event loop. Your worker's onmessage() function will be called, which queues a message to the main thread. That message might already be picked up by the main thread even before the worker's postMessage() completes. (Of course, that might also happen on the other way around, if the worker is idle.)

Intermediate importScripts() in the worker are synchronous and block the worker, not the main thread.

An alternative to synchronous blocking importScripts() are module workers with new Worker('worker.js', {type: 'module'}) . Those replace importScripts() with asynchronous import() or synchronous import . Few browsers support that as of now. Blink does, but for Opera I don't know how it can support module worker without import in worker .

(For more try this module worker article .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM