What are web workers and how to use them

7

Through searches I understand that Web Workers allow the concurrency of processes in JavaScript. It would be like firing a thread JavaScript that updates the View .

Can you consider the adaptation of the MVC pattern to JavaScript? I would like more information and especially the care in its use.

    
asked by anonymous 14.01.2015 / 20:36

1 answer

4

In fact, a Web Worker is similar to a thread separate from the principal. However, it is completely isolated from both the DOM and the View ), so the only way to communicate between it and the main thread is through % use of%. In addition to the DOM, it also does not have access to other functionalities and global variables / functions / classes available to common scripts.

The main utility of a Web Worker is to separate a heavy / time-consuming process into a separate > process / process that would otherwise totally block the page until it is complete. An example use would be:

script_normal.js

// Cria o web worker
var worker = new Worker('web_worker.js');

// Diz o que fazer quando o web worker enviar uma mensagem
worker.addEventListener('message', function(e) {
    var dados = e.data;
    alert("O resultado é: " + dados.resultado);
});

// Manda uma mensagem pro web worker
worker.postMessage({ cmd:"acharPrimo", n:100 }); // assíncrono - retorna imediatamente

web_worker.js

// Diz o que fazer quando outro thread enviar uma mensagem
addEventListener('message', function(e) {
    var dados = e.data;
    if ( dados.cmd == "acharPrimo" ) {
        var ret = acharPrimo(dados.n); // Chama uma função demorada
        postMessage({ resultado:ret }); // Manda o resultado como mensagem
    }
    // Outras funções, se aplicável
});

function acharPrimo(n) {
    // Acha o n-ésimo primo, construindo um crivo, etc...
}

That is, when the page starts the lengthy process, it does not "hang" until this process is ready - you can continue to use it, just as you would if you had made an Ajax pro server call (except that , in which case everything is happening in the browser itself). This process occurs in parallel, and when it finishes it sends the results to the page (in an asynchronous event) that can then do something with it. Both the page and worker can send multiple messages to each other - for example, to display the user a progress bar.

One thing you need to take care of is to send messages: the main thread and the worker have separate address space (i.e., they do not share memory). This means that all data passed from one to the other is serialized in a string before being sent. In the example shown, when it passed:

{ cmd:"acharPrimo", n:100 }

pro worker , it was not an object that was passed, but a string representing that object. In this case, the object was small, but if it was something big (like an array with multiple elements) its copy from one to the other - by string representation, on top of it - could have a significant impact on performance. There is an alternative - not yet widely supported, at least the last time I checked - that would be the use of transferables , objects whose" property "is transferred from one thread to another. That is, the same object that was once in a thread now happens to be in another, making it inaccessible to the first, but without any copy at all.

Another necessary precaution would be to remember that the web worker itself is single-threaded , ie: after a time-consuming process has begun, it has to go all the way before another begins. It can send messages to the main thread at will, but the reciprocal is not true: as long as this code does not finish executing, messages sent to the worker will be queued until the same available.

A corollary is that you can not "kill" the process by sending a stop message to it - because that message would only be received after the process has even ended ... In such a case, it would be preferable for your worker only to execute a single iteration of the loop at a time, pausing before executing the next one (giving time for pending messages to be processed). And, of course, if you have two or more processes to perform, either you create two workers or ensure that one of them is idle before reusing it (a pool workers is better than always creating a new one because it eliminates the overhead of creation).

Lastly, it should be noted that a common% share is only accessible to the thread that created it (either the primary or the web worker ), share a worker with others through the use of a postMessage . Its functionality is very similar to that of a common worker , but its API has some differences, especially in the form of a thread     

14.01.2015 / 22:06