从数组中顺序执行一堆WinJS承诺

时间:2014-12-16 22:34:07

标签: javascript asynchronous coffeescript promise winjs

我有一系列要按顺序下载的网址,当时有2个网址。

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

循环应该使用一些异步函数下载所有URL,当时按照它们出现在数组中的顺序下载2个URL。 基本顺序循环使用.reduce完成,其工作方式如下:

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());

现在我想同时引入2个URL的并行下载。

所以它会下载:[url1,url2]然后是[url3,url4],最后是[url5]

此功能的结果也应该是每个下载承诺的结果,类似于WinJS.Promise.join的工作方式。

1 个答案:

答案 0 :(得分:2)

让我们抽象出将数组分解为元组的函数

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

以及为每个项目执行工作的功能:

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);
        }
    });
}

并行处理多个项目的函数只是

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

所以我们现在可以在生成序列时使用它:

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([]));

结果数组通过p链传递,每个步骤后都会增长。