Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 WebWorkers, timed function

I am trying to get a WebWorker to count to 100 and update a div with the value of I, currently the div just updates straight to 100 and seems to ignore the interval....

JavaScript (webworker file):

 self.addEventListener('message', function (e) {

        switch (e.data) {

            case 'Hi Worker':
                postMessage('Hi Boss');
                break

            case 'Count to 100':
                var i;
                for (i = 0; i < 100; i++) {
                    setInterval(postMessage(i + 1), 1000);
                }

                break;
            default:
                self.postMessage("Not sure how to help with that");
        }

    }, false);

Main file:

           <script>
            var worker = new Worker('worker.js');

            worker.addEventListener('message', function (e) {
                console.log("worker said: " + "'" + e.data + "'");
                document.getElementById("workerComms").textContent = "worker said: " + e.data;
            }, false);       

        </script>
    </head>
    <body>

        <button onclick="worker.postMessage('Hi Worker');return false;">Say 'Hi Worker'</button>
            <button onclick="worker.postMessage('Count to 100');return false;">Count to 100</button>

            <div id="workerComms">Things workers say...</div>
like image 372
DylanB Avatar asked Jul 13 '26 00:07

DylanB


1 Answers

setInterval(postMessage(i + 1), 1000); calls postMessage(i + 1) and then passes the return value into setInterval, exactly the way foo(bar()) calls bar and passes the return value into foo.

Instead:

  1. You want to pass a function reference to setInterval

  2. You want to use setTimeout, not setInterval

  3. You want to vary the timeout, because otherwise they'll all happen stacked on top of each other one second later

Something like:

for (i = 1; i <= 100; i++) {
    setTimeout(postMessage.bind(window, i), 1000 * i);
}

would probably do it. That schedules 100 timers, at one-second intervals. It uses postMessage.bind(window, i) to create a function that, when called, will all postMessage with this set to window and passing in i as the first argument. I did i from 1 to 100 rather than 0 to 99 to avoid having to add 1 to it in both places I used it.

Alternately, you could ditch the for loop entirely and use setInterval or a chained series of setTimeout. Here's the setInterval:

var i = 0;
var timer = setInterval(function() {
    postMessage(++i);
    if (i >= 100) {
        clearInterval(timer);
    }
}, 1000);
like image 192
T.J. Crowder Avatar answered Jul 15 '26 15:07

T.J. Crowder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!