• as works like wrap except that if you give it a promise, it just returns that promise. If you give a promise to wrap, it wraps it in another promise. • join aggregates promises into a single one that’s fulfilled when all the values given to it, including other promises, are fulfilled. This essentially groups promises with an AND operation (using then, so you’ll want to call the join’s done method to handle errors appropriately). • any is similar to join but groups with an OR (again using then). • cancel stops an async operation. If an error function is provided, it’s called with a value of Error("canceled"). • theneach applies completed, error, and progress handlers to a group of promises (using then), returning the results as another group of values inside a promise. • timeout has a dual nature. If you just give it a timeout value, it returns a promise wrapped around a call to setTimeout. If you also provide a promise as the second parameter, it will cancel that promise if it’s not fulfilled within the timeout period. This latter case is essentially a wrapper for the common pattern of adding a timeout to some other async operation that doesn’t have one already. • addEventListener/removeEventListener (and dispatchEvent) manage handlers for the error event that promises will fire on exceptions (but not for cancellation). Listening for this event does not affect use of error handlers. It’s an addition, not a replacement. 27 In addition to using functions like as and wrap, you can also create a promise from scratch by using new WinJS.Promise( [, ). Here is a function that accepts completed, error, and progress dispatchers, and oncancel is an optional function that’s called in response to WinJS.Promise.cancel. The dispatchers are what you call to trigger any completed, error, or progress handlers given to the promise’s then or done methods, whereas oncancel is your own function that the promise will call if it’s canceled. Creating a new promise in this way is typically done when you create an async function of your own. For example, we’ll see how this is used to encapsulate an async web worker in Chapter 16, “WinRT Components.” Also, if WinJS.Promise.as doesn’t suffice, creating a promise like this is useful to wrap other operations (not just values) within the promise structure so that it can be chained or joined with other promises. For example, if you have a library that talks to a web service through raw async XmlHttpRequest, you can wrap each API of that library with promises. You might also use a new promise to combine multiple async operations (or other promises!) from different sources into a single promise, where join or any don’t give you the control you need. Another example is encapsulating specific completed, error, and progress functions within a promise, such as to implement a multiple retry 27 Async operations from WinRT that get wrapped in promises do not fire this error event, which is why you typically use an error handler instead. 134

mechanism on top of singular XHR operations, to hook into a generic progress updater UI, or to add under-the-covers logging or analytics with service calls so that the rest of your code never needs to know about them. What We’ve Just Learned • How the local and web contexts affect the structure of an app, for pages, page navigation, and iframe elements. • How to use application content URI rules to extend resource access to web content in an iframe. • Using ms-appdata URI scheme to reference media content from local, roaming, and temp appdata folders. • How to execute a series of async operations with chained promises. • How exceptions are handled within chained promises and the differences between then and done. • Methods for getting debug output and error reports for an app, within the debugger and the Windows Event Viewer. • How apps are activated (brought into memory) and the events that occur along the way. • The structure of app activation code, including activation kinds, previous execution states, and the WinJS.UI.Application object. • Using extended splash screens when an app needs more time to load, and deferrals when the app needs to use async operations on startup. • The important events that occur during an app’s lifetime, such as focus events, visibility changes, view state changes, and suspend/resume/terminate. • The basics of saving and restoring state to restart after being terminated, and the WinJS utilities for implementing this. • Using data from services through WinJS.xhr and how this relates to the resuming event. • How to achieve page-to-page navigation within a single page context by using page controls, WinJS.Navigation, and the PageControlNavigator from the Visual Studio/Blend templates, such as the Navigation App template. • All the details of promises that are common used with, but not limited to, async operations. 135