It occasionally comes up that you need to serially iterate over a synchronous collection, but doing so involves async APIs. For example, you have a vector of StorageFile objects and want to call copyAsync on each of them, one at a time, in the order of the vector.

This can be accomplished with the following code (thanks to Adam Comella for this solution). Assuming that storageItems is the list over which you want to iterate and destination is the folder into which you want to copy those items, you can do this:

var storageItemsPromise = WinJS.Promise.as();
storageItems.forEach(function (item) {
     storageItemsPromise = storageItemsPromise.then(function () {
         return item.CopyAsync(destination);
     });
});
// Call done so that if CopyAsync throws an exception, it’ll cause the app to terminate
storageItemsPromise.done();


One Comment

  1. Posted May 8, 2013 at 9:47 am | Permalink

    We have these two helpers in our project. Of course they’re easily convertible into normal functions if you’re not a fan of monkey-patching:

    Array::eachAsync = (fn) ->
    promises = @map (item, index, collection) -> fn(item, index, collection)
    WinJS.Promise.join(promises)

    Array::sequentialEachAsync = (fn) ->
    @reduce (lastPromise, item) ->
    lastPromise.then () -> fn(item)
    , WinJS.Promise.as()