locked
Why do some events have setPromise() and others getDeferral()?

    Question

  • Whats the difference between the two?
    Friday, March 15, 2013 11:06 AM

Answers

  • getDeferral is the mechanism that's used at the level of WinRT. setPromise is a WinJS wrapper around that mechanism that's typically used in contexts where there's another WinJS wrapping going on.

    For example, with app activation, the WinRT event is Windows.UI.WebUI.WebUIApplication.onactivated. The event args to this contains a getDeferral. You call this to get a deferral object whose complete method you call when the splash screen can be taken down. The purpose of this, as you probably know, is to allow you to do async operations within the activated handler and defer the removal of the default splash screen. That is, once you return from the onactivated handler, Windows will assume it can take down the splash screen unless you've requested a deferral, in which case it then waits until you call the deferral's complete.

    WinJS.Application.onactivated wraps the WinRT onactivated method (among others, which is why it exists in the first place), and instead of surfacing the raw deferral mechanism, its args contains a setPromise method. Under the covers, WinJS is always requesting the WinRT deferral object, to allow for async operations in the onactivated handler, primarily WinJS.UI.processAll (which is async). In this case, the deferral's completion is tied to fulfillment of whatever promise you give to setPromise.

    This is why you see args.setPromise(WinJS.UI.processAll()); in the templates by default. WinJS.UI.processAll returns a promise that's fulfilled when all the WinJS controls are instantiates. By passing that promise to args.setPromise, you're saying "when that promise is fulfilled, call the deferral's complete method."

    If you provide a completed handler to the async operation, e.g. processAll, then the promise isn't fulfilled until your completed handler returns, so you can do whatever work you want inside that handler knowing that the splash screen will still be up during that time.

    I go into this in a little more detail in the "Activation Deferrals" section of Chapter 3 of my book (page 108 In the PDF). The short of it is again that setPromise is a WinJS wrapper for the WinRT getDeferral mechanism.

    Kraig

    Author, Programming Windows 8 Apps with HTML, CSS, and JavaScript, a free ebook from Microsoft Press


    • Marked as answer by phil_ke Friday, March 15, 2013 5:02 PM
    Friday, March 15, 2013 3:52 PM

All replies

  • getDeferral is the mechanism that's used at the level of WinRT. setPromise is a WinJS wrapper around that mechanism that's typically used in contexts where there's another WinJS wrapping going on.

    For example, with app activation, the WinRT event is Windows.UI.WebUI.WebUIApplication.onactivated. The event args to this contains a getDeferral. You call this to get a deferral object whose complete method you call when the splash screen can be taken down. The purpose of this, as you probably know, is to allow you to do async operations within the activated handler and defer the removal of the default splash screen. That is, once you return from the onactivated handler, Windows will assume it can take down the splash screen unless you've requested a deferral, in which case it then waits until you call the deferral's complete.

    WinJS.Application.onactivated wraps the WinRT onactivated method (among others, which is why it exists in the first place), and instead of surfacing the raw deferral mechanism, its args contains a setPromise method. Under the covers, WinJS is always requesting the WinRT deferral object, to allow for async operations in the onactivated handler, primarily WinJS.UI.processAll (which is async). In this case, the deferral's completion is tied to fulfillment of whatever promise you give to setPromise.

    This is why you see args.setPromise(WinJS.UI.processAll()); in the templates by default. WinJS.UI.processAll returns a promise that's fulfilled when all the WinJS controls are instantiates. By passing that promise to args.setPromise, you're saying "when that promise is fulfilled, call the deferral's complete method."

    If you provide a completed handler to the async operation, e.g. processAll, then the promise isn't fulfilled until your completed handler returns, so you can do whatever work you want inside that handler knowing that the splash screen will still be up during that time.

    I go into this in a little more detail in the "Activation Deferrals" section of Chapter 3 of my book (page 108 In the PDF). The short of it is again that setPromise is a WinJS wrapper for the WinRT getDeferral mechanism.

    Kraig

    Author, Programming Windows 8 Apps with HTML, CSS, and JavaScript, a free ebook from Microsoft Press


    • Marked as answer by phil_ke Friday, March 15, 2013 5:02 PM
    Friday, March 15, 2013 3:52 PM
  • Thanks Kraig for explaining this so thoroughly.

    Do you know why WinJS did not wrap the Windows.UI.WebUI.WebUIApplication.resuming event but only the "suspending"? Or am I missing something?

    Friday, March 15, 2013 5:04 PM
  • You're welcome, Phil.

    I asked the WinJS team the same question about the resuming event. The design philosophy for WinJS was to wrap only when there was value to add. WinJS doesn't have anything to add for resuming, so they didn't create a wrapper for its own sake.

    It's easy to route resuming into WinJS.Application with WinJS.Application.queueEvent, though:

    Windows.UI.WebUI.WebUIApplication.onresuming = function () {
        app.queueEvent({ type: "resuming" });
    }

    which you'd then handle like this:

    app.addEventListener("resuming", function (args) {
    });
    See page 118 of the book :)

    Friday, March 15, 2013 5:19 PM
  • Yes it makes sense to not clutter the WinJS API. I will add your code to my app anyway.

    And your book - its great! Thanks!

    Monday, March 18, 2013 9:38 AM
  • I should add that queueEvent can be used for any other event you want to create for WinJS.Application--resuming is just an obvious one. This way you can route all kinds of stuff into that one object.
    Monday, March 18, 2013 3:53 PM
  • I know, I use it in my event based app model.
    Monday, March 18, 2013 6:18 PM