Tuesday, January 31, 2012

WINJS.promise and .then pattern

The whole promise/async programming aspect of Windows 8 isn't very well documented, so this is what I've dredge up:


see http://msdn.microsoft.com/en-us/library/windows/apps/hh464924.aspx
This looks like the proper documentation about the promise thing in msdn:

Asynchronous patterns in the Windows Runtime
Expand
2 out of 2 rated this helpful Rate this topic

Asynchronous patterns in the Windows Runtime

[This documentation is preliminary and is subject to change.]
The Windows Runtime provides a consistent set of patterns for creating and managing asynchronous operations.
The following sections describe asynchronous programming in the Windows Runtime and its representation in JavaScript, C#, Microsoft Visual Basic .NET, and Microsoft Visual C++.

Advantages of asynchronous programming

Your Metro style app remains responsive to user input when it takes advantage of the Windows Runtime asynchronous programming model. You can start a long-running task without blocking the UI thread, and you can receive the results of the task at a later time. You can cancel tasks and receive progress notifications as tasks run in the background. You don't need to manage threads explicitly or interact directly with the underlying concurrence implementation.
Many Windows Runtime features are exposed as asynchronous functions, like MediaCapture and StorageFile. By convention, the names of asynchronous functions end with "Async" to indicate that part of their execution may take place after the call has returned.
When you use asynchronous APIs in your Metro style app, your code makes non-blocking calls in a consistent way. When you implement these asynchronous patterns in your API, callers can understand and use your code in a predictable way.
The Windows Runtime provides asynchronous patterns that are natural for each programming language.
Programming languageAsynchronous representation
JavaScript promise object, then function
Windows Library for JavaScriptPromise object, then function
C#System.Threading.Tasks.Task, await operator
Microsoft Visual Basic .NETSystem.Threading.Tasks.Task, Await operator
Visual C++IAsyncOperation<TResult>

These patterns enable your code to:
  • Subscribe to optional progress notifications
  • Subscribe to completed notifications
  • Start an asynchronous operation
  • Request cancellation of an asynchronous operation
  • Request release of resources by using a close function
  • Retrieve results from a completed asynchronous operation

Asynchronous patterns in Metro style apps with JavaScript

In JavaScript, asynchronous programming follows the Common JS Promises/A proposed standard and works with toolkits like jQuery, Dojo, and Windows Library for JavaScript.
A promise object represents a promise for a future value that will be fulfilled eventually. You get a promise object from a factory function, which by convention has a name that ends with "Async".

Simple asynchronous functions in JavaScript

In many cases, calling an asynchronous function is almost as simple as calling a conventional function. The difference is that you use the then function to assign the handler for the future result of the long-running operation, and to start the operation.
The following code example shows how to create a temporary file asynchronously by using the createFileAsync function.
// Assign the URI to download from.
var uriContoso = new Windows.Foundation.Uri("http://www.contoso.com");

// Get the folder for temporary files.
var tempFolder = Windows.Storage.ApplicationData.current.temporaryFolder;

// Create the temp file asynchronously. 
// The then function implicitly sets up the promise object
// and starts the asynchronous operation.  
tempFolder.createFileAsync("tempfile.txt").then(function (tempFile) {
    console.log("Created temp file at: " + tempFile.path);
});

This is equivalent to the following code example, which doesn't use the then function. Instead, the promise object is used directly and the asynchronous operation is started by calling the start method explicitly.
// Assign the URI to download from.
var uriContoso = new Windows.Foundation.Uri("http://www.contoso.com");

// Get the folder for temporary files.
var tempFolder = Windows.Storage.ApplicationData.current.temporaryFolder;
    
// Get a promise to create the temp file.
var promise = tempFolder.createFileAsync("tempfile.txt");

// Assign the completion handler function.
promise.operation.completed = function (asyncOp) {
    var path = asyncOp.operation.getResults().path;
    console.log("Created temp file at: " + path );
};
    
// Start the asynchronous operation. 
promise.operation.start();

In both cases, your code continues to run, and when the background operation completes, the completion function runs and displays the result of the operation by calling getResults on the provided asyncOperation. You can end the asynchronous operation while it's running by calling the cancel function.

Chained asynchronous functions in JavaScript

You can chain asynchronous operations by calling the then function on the promise that is returned by the previous then function.
The following code example shows how to download a web page asynchronously to a file by using the createFileAsync and startDownloadAsync functions and nested then functions.
// Assign namespace aliases for convenience.
var WS = Windows.Storage;
var WN = Windows.Networking;

// Assign the URI to download from.
var uriContoso = new Windows.Foundation.Uri("http://www.contoso.com");

// Get the folder for temporary files.
var tempFolder = WS.ApplicationData.current.temporaryFolder;

// Create the temp file asynchronously.
tempFolder.createFileAsync("tempfile.txt").
    then(function (tempFile) {
        // The then function gets the result from the asynchronous file-creation operation,
        // which is a StorageFile, and passes it to the anonymous completion handler function.
        // This file is passed to the startDownloadAsync function to be used as the
        // destination file for the download.
        var backgroundDownloader = new WN.BackgroundTransfer.BackgroundDownloader();
        return backgroundDownloader.startDownloadAsync(uriContoso, tempFile);
    }).
    then(function () {
        // The then function starts the async download operation.
        console.log("File download complete.");
    });

The createFileAsync function returns a promise, and the then function assigns the provided completion handler to the promise's operation property. This function executes when the asynchronous operation completes. When the promise is set up, the then function starts the asynchronous operation.

Asynchronous functions with progress and error handling in JavaScript

You can track the progress of an asynchronous operation by providing a notification function. You can get detailed information about error conditions by providing an error function. Use the then function to assign the handler functions for progress notifications and error handling.
The following code example shows how to download a web page asynchronously to a file by using the startDownloadAsync function and notifications.
// Assign namespace aliases for convenience.
var WS = Windows.Storage;
var WN = Windows.Networking;

// Assign the URI to download from.
var uriContoso = new Windows.Foundation.Uri("http://www.contoso.com");

// Get the folder for temporary files.
var tempFolder = WS.ApplicationData.current.temporaryFolder;

// Create the temp file asynchronously.
tempFolder.createFileAsync("tempfile.txt").
    then(function (tempFile) {
        // The createFileAsync call succeeded, so start the download operation.
        var backgroundDownloader = new WN.BackgroundTransfer.BackgroundDownloader();
        return backgroundDownloader.startDownloadAsync(uriContoso, tempFile);
    }).
        then(function () {
            console.log("File download complete.");
    },
        // Define the error handling function.
        function (error) {
            alert("BackgroundDownload failed.");
    },
        // Define the progress handling function.
        function (progress, resultSoFar) {
            console.log("Bytes retrieved: " + progress.bytesReceived);
    });

The createFileAsync function returns immediately. The then function assigns the progress and error handlers, and it starts the asynchronous operation.
When the startDownloadAsync function has updates to report, it calls the progress handler with progress and intermediate result objects. If an error occurs during the asynchronous operation, the error handler is called instead of the completed handler.

Asynchronous patterns in Metro style apps with WinJS

The Windows Library for JavaScript is a toolkit for asynchronous programming. It's based on the Common JS Promises/A proposed standard and works with toolkits like jQuery and Dojo.
A Promise object represents a promise for a future value that will be fulfilled eventually. You get a Promise object from a factory function, which by convention has a name that ends with "Async". The Promise object enables the promise contract for asynchronous operations like data binding and ListView data sources.
The Promise object provides static utility functions for working with promises of many kinds, including Promise and Windows Runtime async operations. For example, the join function enables composing multiple asynchronous operations that all need to complete before the next step in the algorithm executes. For more information, see Asynchronous programming in JavaScript.

Creating your own Promise

In addition to sophisticated utilities, the Promise object enables easy implementation of your own asynchronous functions.

The following code example shows how to create a custom asynchronous function by using the Promise object. The poll function takes a function and an update period, in milliseconds, and returns a Promise that calls the specified function periodically at the specified interval.
function pollAsync(f, interval) {
    //
    // Periodically run the function 'f' until it returns true. Once it
    // returns true, stop polling and fulfill the promise successfully.
    // If it throws an error, stop polling and fulfill the promise
    // with an error.
    //
    var token;
    return new WinJS.Promise(
        function (c, e) {
            token = setInterval(
                function () {
                try {
                    var result = f();
                    if (result) {
                        clearInterval(token);
                        c();
                    }
                } catch (ex) {
                    clearInterval(token);
                    e(ex);
                }
            },
                interval || 1000
            );
        },
        function () {
            // If canceled, clear the interval to stop polling.
            clearInterval(token);
        }
    );
}

// The startPolling function calls the poll function with
// a function that is invoked every 1000 milliseconds.
function startPolling() {

    pollAsync(function () { console.log("poll interval"); }, 1000).
        then(function () {
            console.log("polling canceled"); });
};


Asynchronous patterns in Metro style apps with C#

In C#, asynchronous programming is based on the Task class and the await operator. The Task class represents an asynchronous operation. You get a Task object from a factory function, which by convention has a name that ends with "Async". You provide the code that executes asynchronously by providing an Action delegate. For more information, see Asynchronous Programming with Async and Await (C# and Visual Basic).

Simple asynchronous methods in C#

In many cases, calling an asynchronous method is almost as simple as calling a conventional method. The difference is that you use the await operator to manage the Task that's returned by the asynchronous method. The await operator suspends the execution of the current method until the task is complete. In the meantime, control returns to the caller of the current method. The async modifier on the method declaration is required.
The following code example shows how to create a temporary file asynchronously by using the CreateFileAsync method.
using System.Diagnostics;
using Windows.Storage;
using Windows.Networking.BackgroundTransfer;

async Task CreateTempFileAsync()
{
    // Assign the URI to download from.
    Uri uriContoso = new Uri("http://www.contoso.com");

    // Get the folder for temporary files.
    IStorageFolder tempFolder = Windows.Storage.ApplicationData.Current.TemporaryFolder;

    // Create the temp file asynchronously. The asynchronous operation
    // is created as a Task, and the await operator causes execution 
    // to transfer to the caller of the CreateTempFileAsync method,
    // while the asynchronous operation runs in the background. 
    StorageFileRetrievalOperation op = tempFolder.CreateFileAsync("tempfile.txt");
    Task<StorageFile> task = op.StartAsTask<StorageFile>();
    var tempFile = await task;

    // The following line is equivalent to the previous three lines.
    // var tempFile = await tempFolder.CreateFileAsync("tempfile.txt");

    // When the task completes, control returns to this 
    // method, the result of the task is assigned to tempFile,
    // and the following line executes.
    Debug.WriteLine("Created temp file at: " + tempFile.Path);
}


The CreateTempFileAsync method blocks until the Task created from the StorageFileRetrievalOperation is completed. The await operator causes execution to transfer to the caller while the task runs in the background, and when the task completes, execution transfers back to the tempFile assignment in the CreateTempFileAsync method.
When an app first calls your async method, control does not transfer back to the caller until the first await operator is encountered. Even after the first await operator, execution continues in your async method until an await operator occurs on an incomplete task.
This means that you should write an async method so that it doesn't do a lot of work, or perform blocking calls, before its first await, or between await operators. Asynchronous methods are for operations that don’t need a lot of thread time. If you need to move intensive work or unavoidable blocking calls from your thread, you should put them on the thread pool using the Task.Run method.
When a method has the async modifier, the return type can be only void, Task, or Task<T>. Typically, a return type of void is used only in an async event handler, where void is required. In other cases, you use Task<T> if the completed task returns a value of type T, or Task if the completed task does not return a meaningful value. You can think of the Task return type as meaning Task<void>.

Asynchronous methods with progress and completion handling in C#

You can track the progress of an asynchronous operation by providing a notification delegate. You can get detailed information about the outcome of the operation by providing a completion delegate.
The following code example shows how to download a web page asynchronously to a file by using the StartDownloadAsync function with progress and completion notifications.
using System.Diagnostics;
using Windows.Storage;
using Windows.Networking.BackgroundTransfer;

async Task DownloadWithProgressAndCompletedAsync()
{
    // Assign the URI to download from.
    Uri uriContoso = new Uri("http://www.contoso.com");

    // Get the folder for temporary files.
    IStorageFolder tempFolder = Windows.Storage.ApplicationData.Current.TemporaryFolder;

    // Create the temp file asynchronously. 
    var tempFile = await tempFolder.CreateFileAsync("tempfile.txt");

    // Get a DownloadOperation from the StartDownloadAsync method.
    var backgroundDownloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
    DownloadOperation op = backgroundDownloader.StartDownloadAsync(uriContoso, tempFile);

    // Assign delegates for the Progress and Completed notifications.
    op.Progress = new AsyncActionProgressHandler<BackgroundDownloadProgress>(DownloadProgressEventHandler);
    op.Completed = new AsyncActionWithProgressCompletedHandler<BackgroundDownloadProgress>(DownloadCompletedHandler);

    // Start the asynchronous operation.
    await op.StartAsTask();
}
void DownloadProgressEventHandler(
    IAsyncActionWithProgress<BackgroundDownloadProgress> action,
    BackgroundDownloadProgress progress)
{
    // Report progress on the asynchronous operation. 
    // For example, you could update a ProgressBar control.
    Debug.WriteLine("Bytes retrieved: " + progress.BytesReceived);
}

void DownloadCompletedHandler(IAsyncActionWithProgress<BackgroundDownloadProgress> op)
{
    // Perform actions based on the completion status.
    if (op.Status == AsyncStatus.Error)
    {
        Debug.WriteLine("Error: " + op.ErrorCode);
    }
    else if (op.Status == AsyncStatus.Canceled)
    {
        Debug.WriteLine("Canceled");
    }
    else if (op.Status == AsyncStatus.Completed)
    {
        Debug.WriteLine("Download Completed");
    }
}

The StartDownloadAsync method returns a DownloadOperation, which you use to manage the asynchronous task. Delegates for the Progress and Completed notifications are assigned, and the task is started by calling the Start method.
When the asynchronous task has updates to report, it calls the progress handler with progress and intermediate result objects. The completed handler is called when the task completes, and you can check the result of the task by inspecting the Status property.

Asynchronous methods with anonymous delegates in C#

You can track the progress and get detailed information about the outcome of an asynchronous operation by providing anonymous delegates. This approach avoids the proliferation of handler methods in your code.
The following code example shows how to download a web page asynchronously, with progress and completion notifications that are implemented as anonymous delegates.
using System.Diagnostics;
using Windows.Storage;
using Windows.Networking.BackgroundTransfer;

async Task DownloadWithAnonymousDelegatesAsync()
{
    // Assign the URI to download from.
    Uri uriContoso = new Uri("http://www.contoso.com");

    // Get the folder for temporary files.
    IStorageFolder tempFolder = Windows.Storage.ApplicationData.Current.TemporaryFolder;

    // Create the temp file asynchronously. 
    var tempFile = await tempFolder.CreateFileAsync("tempfile.txt");

    // Get a DownloadOperation from the StartDownloadAsync method.
    var backgroundDownloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
    DownloadOperation op = backgroundDownloader.StartDownloadAsync(uriContoso, tempFile);

    // Assign delegates for the Progress and Completed notifications.
    op.Progress = delegate(
        IAsyncActionWithProgress<BackgroundDownloadProgress> action,
        BackgroundDownloadProgress progress)
    {
        // Report progress on the asynchronous operation. 
        // For example, you could update a ProgressBar control.
        Debug.WriteLine("Bytes retrieved: " + progress.BytesReceived);
    };

    op.Completed = delegate(IAsyncActionWithProgress<BackgroundDownloadProgress> completedOp)
    {
        // Perform actions based on the completion status.
        if (completedOp.Status == AsyncStatus.Error)
        {
            Debug.WriteLine("Error: " + op.ErrorCode);
        }
        else if (completedOp.Status == AsyncStatus.Canceled)
        {
            Debug.WriteLine("Canceled");
        }
        else if (completedOp.Status == AsyncStatus.Completed)
        {
            Debug.WriteLine("Download Completed");
        }
    };

    // Start the asynchronous operation.
    await op.StartAsTask();
}




see http://blogs.msmvps.com/luisabreu/blog/2012/01/19/windows-8-adventures-the-async-pattern-in-javascript/

One of the things you’ll notice when writing Windows 8 Metro applications is that most APIs don’t expose any synchronous methods. If an operation takes more than 15ms to be executed, then you’ll be getting an asynchronous call. And notice that asynchronous is not an option here! It’s simply the only way to go.
If you’re developing Windows 8 Metro apps with JavaScript, then it won’t be long until you meet the WinJS.Promise object (which I’ll be calling Promise from now on). Most (if not all) of the asynchronous method you’ll be using end up returning a Promise. For instance, if you’re trying to create a new file, you’ll probably be using the createFileAsync method. This method returns a Promise which you can then use for being called back when that operation is performed.
(see article for his code)

http://www.sunilrav.com/blog/
has this example of using "then"
function saveStuff(fileName, contentText) {
       var sampleFile;
       // Create file in user's Document library, overwriting the existing file if there is one
       Windows.Storage.KnownFolders.documentsLibrary.createFileAsync(fileName,
        Windows.Storage.CreationCollisionOption.replaceExisting).then(function (file) {
           sampleFile = file;
           // Have file and text to write
           if (sampleFile != null && geoCode != null) {
               // Open file as stream with read/write access
               sampleFile.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function (stream) {
                   // File opened
                   // Prepare and write to the file stream
                   var outputStream = stream.getOutputStreamAt(stream.size);
                   var writer = new Windows.Storage.Streams.DataWriter(outputStream);
                   writer.writeString(contentText);
                   // Save stream to file
                   writer.storeAsync().then(function () {
                       outputStream.flushAsync().then(function () {
                           writeContent('Geocode saved.');
                       });
                   });
               });
           }
       });
   }
Here is an example of a call that returns a promise
FileInformation.OpenAsync | openAsync method
var promise = fileInformation.openAsync(accessMode).then( /* Your success and error handlers here */ );
This is a good presentation:

What is an async api?

file.openAsync(accessMode).then( function (stream) {
// read stuff from file stream
});

JavaScript promises

var picker = new Storage.Pickers.FileOpenPicker();
picker.fileTypeFilter.append (".jpg");
picker.pickSingleFileAync()
.then (function (fi) {
     fi.openAsync(Storage.FileAccessMode.read)
     .then (function (stream) {....


WinJS.Promise object
from http://msdn.microsoft.com/en-us/library/windows/apps/br211867.aspx
WinJS.Promise object
provides a mechanism to schedule work to be done on a value that has not yet been computed. It is an abstraction for managing interactions with asynchronous APIs.

Syntax

var aPromise = new WinJS.Promise(init, onCancel);

Members

The Promise object has the following types of members:

Events

The Promise object has the following events.
EventDescription
onerrorOccurs when there is an error in processing.

Methods

The Promise object has the following methods.
MethodDescription
anyReturns a Promise that is fulfilled when one of the input Promise objects has been fulfilled.
asReturns the specified value as a Promise.
cancelAttempts to cancel the realization of a promised value.
dispatchEventRaises an event of the specified type and with additional properties.
isDetermines whether the specified value is a Promise.
joinCreates a Promise that is fulfilled when all the values are fulfilled.
Promise ConstructorInstantiates a new instance of a Promise.
removeEventListenerRemoves an event listener.
thenSpecifies the work to be done upon fulfillment of the promised value, the error handling to be performed if the Promise fails. and the handling of progress notifications.
theneachPerforms an operation on all of the specified Promise objects and returns a Promise that is in the shape of the input and contains the result of the operation that was performed on each input.
timeoutExecutes a promise after the specified interval.
wrapConverts a non-Promise object into a Promise.
wrapErrorConverts an error to a Promise in an error state.

No comments:

Post a Comment