Right now, I've got this, and it works:
var myWebWorker = new Worker('myWebWorker.js');
myWebWorker.onmessage = function (myEvent) {
$('#Print').append('Return value: ' + myEvent.data + "<br>");
};
myWebWorker.postMessage(2);
My question is: Can I do this instead?
var result = myWebWorker.postMessage(2);
Because I need the web worker to be synchronous - in other words, give a return value and also don't return until you're finished.
Edit 1:
The web worker is doing an insert/select onto a local database using openDatabaseSync transactions.
Edit 2:
It appears that my problem is with Cocoa Touch and not with JavaScript. Here's a clever hack that someone has posted on StackOverflow.
Edit 3:
Here's a better hack.
The point of web workers is to delegate tasks without blocking the UI. They can't be synchronous.
You probably don't need the task to be synchronous but you need to design your code around events and asynchronous tasks just like you can't design any javascript application nor any serious GUI application with only synchronous operations.
As already said, you can't call the worker synchronously. You could write a wrapper that waits for the worker to return a message, but that has the same effect as executing the worker's code directly in you caller's code. The caller would be blocked for the time the worker code runs.
When you should use workers:
CPU1 CPU2 Explanation
A # Main script starts (in one Thread/CPU)
| # still runs...
|---->B # Offload some heavy work to Worker B (to another Thread/CPU)
| | # A can do other stuff while B does some heavy work that would block A
|<----B # B is ready and posts the result to A
| # A is interrupted only shortly by B's message
V
I hope this makes things clearer.
I am hesitating to add this code (i.e., please rethink your need for calling a Worker synchronously), but even writing a sync wrapper does not work (Thx to the commenters):
function syncMe(){
var w = new Worker('myWebWorker.js');
var data = null, ready = false;
w.onmessage = function (e) {
ready = true;
data = e.data;
};
w.postMessage(2)
while(!ready){ /* block this thread forever, since `ready` is never changed */ }
console.log(data);
}
Edit: "Why You can't sync a worker like this"
The onmessage
handler will never be called because the JavaScript VM can only call one function a time and the syncMe
function has not yet exited. (Sorry for the confusion)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With