Friday, January 04, 2013

WinJS Promises Run in Sequence

Sometime we need to invoke a series of asynchronous calls (WinJS Promise objects) in sequence, i.e. wait for the first promise to complete and then start the second promise and so on. One way of doing that is by recursive calls as following demo code:

(function () {
    "use strict";
    
    // Download a link asychronously
    function downloadAsync(url) {
        console.log(url + " starting...");
        return WinJS.xhr({ url: url}).then(function () {
            console.log(url + " completed");
        }, function (err) {
            console.log(url + " error: " + err);
        });
    }
    
    // Recersivly download links asychronously
    function downloadRecursiveAsync(urls) {
        if (urls && urls.length > 0) {
            var url = urls[0];
            var remainUrls = urls.slice(1);
            return downloadAsync(url).then(function () {
                return downloadAsyncRecursive(remainUrls);
            });
        } else {
            return WinJS.Promise.as();
        }
    }

    WinJS.UI.Pages.define("/pages/home/home.html", {
        ready: function (element, options) {
            var testUrls = ["http://aa.com", "http://bb.com", "http://cc.com"];
            var promises = [];

            console.log("Start multiple downloads asynchronously without sequence.");
            for (var i = 0; i < testUrls.length; i++) {
                promises.push(downloadAsync(testUrls[i]));
            }

            WinJS.Promise.join(promises).then(function () {
                console.log("All asynchronous downloads completed without sequence.");
            }).then(function () {
                console.log("Start multiple download asynchronously in sequence.");
                downloadRecursiveAsync(testUrls).then(function () {
                    console.log("All asynchronous downloads completed in sequence.");
                });
            });
        }
    });
})();

Console log:

Start multiple downloads asynchronously without sequence.
http://aa.com starting...
http://bb.com starting...
http://cc.com starting...
http://bb.com completed
http://cc.com completed
http://aa.com completed
All asynchronous downloads completed without sequence.
Start multiple download asynchronously in sequence.
http://aa.com starting...
http://aa.com completed
http://bb.com starting...
http://bb.com completed
http://cc.com starting...
http://cc.com completed
All asynchronous downloads completed in sequence.