23.01.2018 Views

MICROSOFT_PRESS_EBOOK_PROGRAMMING_WINDOWS_8_APPS_WITH_HTML_CSS_AND_JAVASCRIPT_PDF

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

When this worker is started, the only code that executes is the onmessage assignment. When that<br />

handler receives the appropriate message, it then invokes countFromZero, which in turn posts its results.<br />

In other words, setting up a worker just means converting method calls and results into messages.<br />

Invoking this method from the app now looks like this:<br />

var worker = new Worker('worker_count.js');<br />

worker.onmessage = function (e) { //e.data.sum is the result }<br />

//Call the method<br />

worker.postMessage({ method: "countFromZero", max: 1000, increment: .00005 });<br />

Keep in mind with all of this that postMessage is itself an asynchronous operation—there’s no<br />

particular guarantee about how quickly those messages will be dispatched to the worker or the app.<br />

Furthermore, when a worker is created, it won’t start executing until script execution yields (as when you<br />

call setImmediate). This means that workers are not particularly well suited for async operations that you<br />

want to start as soon as possible or for those where you want to get the results as soon as they are<br />

available. For this reason, workers are better for relatively large operations and ongoing processing;<br />

small, responsive, and high-performance routines are better placed within WinRT components.<br />

The postMessage mechanism is also not the best for chaining multiple async operations together, as<br />

we’re easily able to do with promises that come back from WinRT APIs. To be honest, I don’t even want<br />

to start thinking about that kind of code! I prefer instead of ask whether there’s a way that we can<br />

effectively wrap a worker’s messaging mechanism within a promise, such that we can treat async<br />

operations the same regardless of their implementation.<br />

To do this, we somehow need a way to get the result from within the worker.onmessage handler and<br />

send it to a promise’s completed handler. To do that, we use a bit of code in the main app that’s<br />

essentially what the JavaScript projection layer uses to turn an async WinRT API into a promise itself:<br />

// This is the function variable we're wiring up.<br />

var workerCompleteDispatcher = null;<br />

var promiseJS = new WinJS.Promise(function (completeDispatcher, errorDispatcher,<br />

progressDispatcher) {<br />

workerCompleteDispatcher = completeDispatcher;<br />

});<br />

// Worker would be created here and stored in the 'worker' variable<br />

// Listen for worker events<br />

worker.onmessage = function (e) {<br />

if (workerCompleteDispatcher != null) {<br />

workerCompleteDispatcher(e.data.sum);<br />

}<br />

}<br />

promiseJS.done(function (sum) {<br />

// Output for JS worker<br />

});<br />

735

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!