Promises and Asynchron calls in Metro Application using JavaScript

Promises and Asynchron calls in Metro Application using JavaScript

The new Windows introduced us to a new type of applications called Metro Applications. These applications are designed to use as few resources as possible and to be used very easily on tablets. Metro Applications can be written not only in XAML and C# but also in HTML5 and JavaScript. This is something new for the Microsoft world; we can develop native applications in JavaScript. Now JavaScript is a first-class citizen in Metro world.

Of course we cannot talk about Metro Applications without talking about asynchrony methods. We need this type of methods just as much as we need water. When we make a call to a service or we want to write something to the disk we need these calls to be asynchronous.

The most used pattern for asynchronous calls in JavaScript is the callback pattern, where we specify the callback functions as parameters. They will be called when the given actions ends. This pattern is often used in jQuery worlds.

Microsoft decides to use another well-know standard for asynchronous calls. The guys from Common/JS propose another standard that was adopted by Microsoft. The name of this standards is Promises/A and it is very similar with how asynchronous task work on .NET 4.5. Also this standard is based on the fluent pattern, which makes it easier for us to read and understand any written code. If you already worked with Node.js, Ruby or jQuery 1.5 maybe you already used this standard without knowing.

Basically a promise represents a value that will be fulfilled in the future. The exact moment cannot be defined. In a Metro Application written in JavaScript any promise will return an object that has two methods whichare very important and similar – then and done.

 promise.then(onComplete, onError, onProgress)

The then methods have three parameters where we can specify the functions (handlers) that will be called when:

onComplete – the call ends with success

onError – is called during the execution of a code if an error appeared

onProgress – a function that is called when the promise reports progress.

Of course we can omit any of the 2nd or 3rd parameters. The only one that is mandatory is the first one. The done function has the same signature as the then function.The difference is the error handling. This function will throw any error that appeared in the call execution, in comparison with the then function that will only return an error state.

Using these promises we don’t need to rely on anonymous functions that are defined inline. We can define functions in our code that can be specified in the then or done. When an error is thrown it makes it easier to detect the original location of the exceptions.

In Metro Applications all the Windows Runtime and Windows Libraries for JavaScript are defined using this standard. This is the reason why you have to know this standard.

fooWebService.get("http://www.microsoft.com")
.then(function(result) {
// process result
return fooWebService.get("http://windows.azure.com/")
})
.then(function(result) {
// process result
}

We can have as many then functions appended one after another as we want. The condition is to have an onComplete function in each one in order to return another promise. If we don’t, the onComplete of the second one will be immediately called, without waiting for the response of the first call.

The WinJS.Promise object defined by the framework came with some helper methods. Besides the then and done functions the most important functions are:

join – creates a promise that permits us to specify a list of promises and the onComplete is called only when all these promises are fulfilled.
any – creates a promise that is fulfilled when one of the promises is fulfilled
wrap – wraps a non-promise function into a promise. It is very useful when we have a chain of promises.

For example we can use any to wait for any specified promises from the list to be fulfilled. When one of them is fulfilled the callback is automatically called.

WinJS.Promise.any([someMethod1Async(), someMethod2Async("someParam")])
.then(function() { console.log("done");});

Promises are not only defined by the system, we can also define promises very easily. When we create a promise we need to create and return a WinJS.Promise object. The constructor accepts a function that has three parameters (the onComplete, onError, onProgress parameters). In the next example we define a promise that waits for 10 seconds and calls the complete function (this is a classic example):

function wait10SecondsAsync() {
return new WinJS.Promise(function (onComplete, onError, onProgress) {
var seconds = 10;
var intervalId = window.setInterval(function () {
seconds--;
onProgress(seconds);
if (seconds
window.clearInterval(intervalId);
onComplete();
}
}, 1000);
});
}

In the end some small hints when working with promises:

  • Always name suffix using an asynchronous method with “Async”
  • When more than one promise is bound don’t forget to return the promises on each onComplete function
  • For the last call of an asynchronous chain call it is recommended to use done and not then (done throws any exceptions to the upper code)
  • Use WinJS.Promise.any and WinJs.Promise.wait when you need to wait for one or more promises

In conclusion promises are very powerful when we are talking about asynchronous calls in the JavaScript language. When clever used, promises can help us not only write beautiful code but the code almost writes itself.

Tags: ,

You can be the first one to comment on this story.

Leave a Reply

Your email address will not be published. Required fields are marked *