A few week ago I answered a question on the MSDN forums that basically asked, “I ran code in a promise, so why didn’t it run asynchronously.” It was a good opportunity to clarify the nature of a promise and the relationship between promises and asynchronous code. So here I offer an edited version of my response.

The basic thing to understand is that a promise is just a way of saying “execute this code when the promised value becomes available (that is, when the promise of that value is fulfilled).” It says nothing about how the code is actually run in the CPU scheduler. So if you take a block of code and just wrap it with WinJS.Promise.as or such, e.g.:

return new WinJS.Promise(function (complete) {  /* some code */ });

you’re just saying that /* some code */ will execute when you call the promise’s then/done methods, but all that still happens on the UI thread.

True async behavior–that is, running code on another thread–happens through three means:

  1. A JavaScript worker (web worker), which you can wrap in a promise (new WinJS.Promise to handle the worker messages) in order to chain/join the async operation to others.
  2. An async method written in a C#/VB WinRT component where the code uses the Task class.
  3. An async method written in a C++ WinRT component where the code uses the concurrency library.

In the latter two cases, async methods (including those from the built-in WinRT APIs) happen to be projected into JavaScript as promises; in #1 you use new WinJS.Promise to do the same manually. But in every case, it’s not the promise that runs code on another thread–it’s purpose is just to manage completed/error/progress handlers. It’s the underlying worker or async method that runs code on another thread.

Creating async APIs in WinRT components as well as with web workers is something I cover in Chapter 16 of my book, in the section “Implementing Async Methods,” if you want all the details.

Here’s a link to the original forum discussion where I extract some of those details.

Comments are closed