Reputation: 1280
I have tried to look through the web-worker documentation, and while I haven't found what I'm looking for, the documentation also isn't great, so I figured I'd just ask about it.
I am working on a mobile application using Cordova that talks to an external device. There are some commands that I need to send to the external device every second. For these, I have set up Web Workers, which is basically the JavaScript equivalent of threads. But there is a command which, to work, must corner the external device. That is to say, the command will fail if the device gets any other commands while trying to process it. To that end, I simply want to suspend my threads.
In Java this would be easy. There is a public void thread.suspend() then, later, thread.resume(). My natural inclination is that Web Workers would have this as a default function. Worker.suspend(), worker.resume(), but I can't find any documentation that supports the idea that Workers have this, despite being a pretty common expectation for multithreading. Is there such an inherent function? If not, is there a best practice for implementing a similar function?
Upvotes: 4
Views: 2796
Reputation:
This snippet shows how to
Because of the limitations of StackOverflow snippets, the web worker code is inline.
function getInlineJS() {
var js = $('[type="javascript/worker"]').text();
var blob = new Blob([js], {"type": "text/plain"});
return URL.createObjectURL(blob);
}
var worker_list = [];
var worker_num = 3;
var pause_count = null;
function create_workers() {
var index;
for (index = 0; index < worker_num; index++) {
var web_worker = new Worker(getInlineJS());
var counter_selector = '#counter' + (index + 1);
(function(selector) {
web_worker.onmessage = function(event) {
var paused = event.data['paused'];
if (paused) {
pause_count++;
}
if (pause_count == worker_num) {
// At this point we know the workers have all stopped
$('#pause_count').text(pause_count);
}
var counter = event.data['counter'];
$(selector).text(counter);
}
})(counter_selector);
worker_list.push(web_worker);
}
}
/**
* Send a bogus message to get the workers to send their counters
*/
function update_counters() {
var index;
for (index = 0; index < worker_num; index++) {
var message = {'index': index};
worker_list[index].postMessage(message);
}
}
/**
* Send the pause flag to the workers
* @param pause_state
*/
function pause_counters(pause_state) {
var index;
for (index = 0; index < worker_num; index++) {
var message = {'pause_flag': pause_state};
worker_list[index].postMessage(message);
}
}
var pause_state = false;
$(document).ready(function() {
create_workers();
setInterval(update_counters, 1000);
$('#pause').on('click', function() {
pause_state = !pause_state;
if (pause_state) {
pause_count = 0;
}
else {
$('#pause_count').text('');
}
pause_counters(pause_state);
$('#pause').text(pause_state ? 'Start' : 'Stop');
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Web Worker</title>
</head>
<body>
<div class="counter">
Counter 1: <span id="counter1"></span>
</div>
<div class="counter">
Counter 2: <span id="counter2"></span>
</div>
<div class="counter">
Counter 3: <span id="counter3"></span>
</div>
<div class="button">
<button id="pause" type="button">Stop</button>
</div>
<div>
Pause Count: <span id="pause_count"></span>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.js"
integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA="
crossorigin="anonymous"></script>
<script src="sync.js"></script>
<script type="javascript/worker">
var pause_flag = false;
var counter = 0;
function run_command() {
if (!pause_flag) {
counter++;
}
}
var interval = setInterval(run_command, 1000);
onmessage = function(event) {
if ('pause_flag' in event.data) {
pause_flag = event.data['pause_flag'];
}
var message = {
"paused": pause_flag,
"counter": counter
};
postMessage(message);
};
</script>
</html>
Upvotes: 2