Windows 8 adventures: the async pattern in JavaScript

After a small detour into ASP.NET MVC, I’m back into my “Windows 8 application development study”. 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. To illustrate this point, lets see some code which creates a new file inside a new folder. Here’s our first try:

function createFolderAndFile() {
    //create new folder inside temp folder
    var tempFolder = Windows.Storage.ApplicationData.current.temporaryFolder;
    tempFolder.createFolderAsync("testFolder",
    Windows.Storage.CreationCollisionOption.openIfExists)
    .then(function (folder) {
        folder.createFileAsync("testFile.txt")
        .then(function (file) {
            file.openAsync(Windows.Storage.FileAccessMode.readWrite)
            .then(function (dataStream) {
                var stream = dataStream.getOutputStreamAt(0);
                var writer = new Windows.Storage.Streams.DataWriter(stream);
                writer.writeString("Howdy, there!");
                writer.storeAsync()
                .then(function () {
                    //don't do anything in callbacks
                    stream.flushAsync()
                    .then(function () { }, function (err) { var r = ""; });
                });
            });
        });
    });
}

Wow!!! I’ve written the code and I’m already lost here! Fortunately, you can improve this code by returning promises from your .then methods. By doing that, you can write code which is a little bit more linear. Here’s our initial example rewritten:

 
function createFolderAndFile() {
    //create new folder inside temp folder
    var tempFolder = Windows.Storage.ApplicationData.current.temporaryFolder;
    tempFolder.createFolderAsync("testFolder", Windows.Storage.CreationCollisionOption.openIfExists)
        .then(function(folder) {
                return folder.createFileAsync("testFile.txt")
        }).then(function(file) {
                return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
        }).then(function(dataStream) {
            var stream = dataStream.getOutputStreamAt(0);
            var writer = new Windows.Storage.Streams.DataWriter(stream);
            writer.writeString("Howdy, there!");
            return writer.storeAsync()
                .then(function() {
                    return stream.flushAsync();
                });
        });
}

I’d say that this is better (at least, from a readability point of view). What do you think?

Btw, I’m almost positive that you’ve notice the empty then calls on the flishAsync method? Well, I’m still not sure why, but the thing is that “empty” call is needed in order for the bytes to be saved to the file. If you remove the .then call, you’ll end up with an empty file (no, are we talking about a bug here?? )

And that’s it for now. Stay tuned for more.

Advertisements

~ by Luis Abreu on January 19, 2012.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: