简体   繁体   中英

Sequentially execute a bunch of WinJS promises from an array

I have an array of URLs that I want to download sequentially, 2 URLs at the time.

var urls = [url1,url2,url3,url4,url5];

The loop should download all the URLs using some async function, 2 urls at the time in the order they appear in the array. The basic sequential loop is done using .reduce that works like this:

preloadPromise = urls.reduce(function(p, url) {
  return p.then(WinJS.Utilities.Scheduler.schedulePromiseBelowNormal).then(function() {
    return preloadOneAsync(url);
  }).then(null, function(error) {
    if (error.name !== "Canceled") {
      logger.error("Could not create preloaded " + url, error);
    }
  });
}, WinJS.Promise.as());

Now I want to introduce parallel downloads of 2 URLs at the same time.

So it would download: [url1,url2] then [url3,url4] and finally [url5]

Also the result of the function should be the results of every download promise, similar to how WinJS.Promise.join works.

Let's abstract out the function to break the array into tuples

function chunkBy(array, n) {
    var chunks = [];
    for (var i=0; i<array.length; i+=n)
        chunks.push(array.slice(i, n));
    return chunks;
}

and the function that does the work for each item:

function tryToLoad(url) {
    return WinJS.Utilities.Scheduler.schedulePromiseBelowNormal() // not sure
    .then(function() {  return preloadOneAsync(url); })
    .then(null, function(error) {
        if (error.name !== "Canceled") {
            logger.error("Could not create preloaded " + url, error);
        }
    });
}

A function that does the work for multiple items in parallel would be just

function loadAll(urls) {
    return WinJS.Promise.join(urls.map(tryToLoad));
}

so we can now use this in the generation of the sequence:

preloadPromise = chunkBy(urls, 2).reduce(function(p, urls) {
    return p.then(function(prevResults) {
        return loadAll(urls).then(function(results) {
            return prevResults.concat(results);
        });
    });
}, WinJS.Promise.as([]));

The array of results is passed through the p chain, always growing after each step.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM