One, foreword

After HTML5 came out, there are many new features worth our attention, one of which is Web worker. I believe those of you who care about front-end development have heard of this even if you haven’t used Web workers. Today we are going to talk about Web workers.

Two, basic use

In fact, the function of The Web worker is very simple, that is, it can run a JS file in the background, so we can entrust some time-consuming calculations to the Web worker in actual use. It’s worth noting, however, that you can’t get window/document/parent objects in a Web worker, which I understand to be a completely separate thread from the page. Therefore, if a large number of DOM operations are involved, we cannot rely on the Web worker to complete them. On the contrary, if a large number of calculation work is involved, we can completely hand it over to the Web worker and finally return the calculation results to us. With that said, let’s actually use it.


      
<html>
<head> 
<meta charset="utf-8"> 
</head>
<body>
 
<p>Count:<output id="result"></output></p>
<button onclick="startWorker()">Start to work</button> 
<button onclick="stopWorker()">Stop working</button>
 
<script>
    var w;
    
    function startWorker() {
        w = new Worker('./index.js');
        w.onmessage = function(event) {
            document.getElementById('result').innerHTML = event.data; }}function stopWorker() 
    { 
        w.terminate();
    }
</script>
 
</body>
</html>
Copy the code

We create a Worker object and pass it a JS file as an argument. Note that the worker does not accept file objects, so we need to build a simple server locally to run the example. The contents of index.js below

var i=0;

function timedCount()
{
    i=i+1;
    postMessage(i);
    setTimeout("timedCount()".500);
}

timedCount();
Copy the code

blog

Third, think deeply

And when you look at this example, do you think it’s pretty simple? Yeah, it’s pretty simple. So let’s try it out again. Our previous latency was 500ms, we now want it to be 1000ms. That’s easy. Let’s go to index.js and change the code. But if in actual production, we can only run a dead JS file, then I think this thing is meaningless, so we need to find a way to dynamically create a JS file and hand it to the Webworker to execute.

4. Create Web workers dynamically

For those unfamiliar with Blob objects and url.createObjecturl, check out their concepts and how to use them, and here we’ll use them to achieve the desired effect. Without further ado, let’s go straight to the code:

<! DOCTYPE html><html>
<head> 
<meta charset="utf-8"> 
</head>
<body>
    
<script>
    function demo() {
        console.log('isok');
    }

    let blob = new Blob([demo.toString() + ' demo()'] and {type: 'text/javascript'});
    let worker = new Worker(URL.createObjectURL(blob));
</script>
 
</body>
</html>
Copy the code

Here we define a demo function, and that’s what we want to run later. This function is then passed as an argument to a new blob object. The blob object is used as an argument to createObjectURL, and the result is used as an argument to the Web Worker. After opening the page, let’s look at the console output:

class MyWorker {
    constructor(f, cb) {
        this.f = f;
        this.worker = null;
        this.onemessage = cb;
    }

    start() {
        const blob = new Blob([`The ${this.f.toString()} The ${this.f.name}(a) `] and {type: 'text/javascript'});
        const url = URL.createObjectURL(blob);
        this.worker = new Worker(url);
        this.worker.onmessage = (event) = > this.onemessage(event.data)
    }

    end() {
        this.worker.terminate(); }}Copy the code

We define a MyWorker, and the parameters passed are the function to be executed and the function to receive the parameters. In this way, we can define a function externally and pass it to the worker as a parameter to realize a dynamic Web worker. Let’s look at the results:


      
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="./MyWorker.js"></script>
    <title>Document</title>
</head>
<body>
    <script>
        function demo() {
            var i = 0;
            function f() {
                postMessage(i);
                i++;
                setTimeout(f, 500);
            }
            f();
        }
        let worker = new MyWorker(demo, function(data) {console.log(data)});
        worker.start();
        setTimeout((a)= > worker.end(), 2000)
    </script>
</body>
</html>
Copy the code

Five, the conclusion

This article provides an idea of how to create a dynamic Web worker. As you can see, we can create a dynamic Web worker using blob and url.createObjecturl, which is much more flexible than running a dead file. At the same time, I have not met the actual application scenario of Web worker. When I meet the application scenario that requires dynamic use of Web worker, I will conduct a thorough study on it.