Promise.map() 进度指示器
Posted
技术标签:
【中文标题】Promise.map() 进度指示器【英文标题】:Promise.map() progress indicator 【发布时间】:2017-12-12 17:30:27 【问题描述】:我正在尝试同时向 JSON API 发送许多 GET 请求。我在 Node.js 中使用 Bluebird Promise,并使用 request-promise 发送 HTTP 请求,如下所示:
const rp = require('request-promise');
//urlsArray is a 5000+ array of urls
Promise.map(urlsArray, url =>
return rp(url)
.then(results =>
return JSON.parse(results);
).catch(err => log(error););
).then(resultsArray =>
log(resultsArray); // print out results
).catch(err =>
log(error);
);
问题在于,如果数组中有 5000 多个 url,请求,即使是并发的,也可能需要很长时间,因为 map() 会等到所有请求都完成。在 map 处理请求时,如何将某种进度指示器(如百分比)打印到控制台?
我在每次请求后都尝试了log(results);
,但这只是在控制台上打印了 5000 个东西,这不是很方便。我更喜欢一个百分比,或者一个显示大约完成了多少的数字。
【问题讨论】:
增加一个计数器并与已知数组长度进行比较 【参考方案1】:请记住,承诺链就是:链。因此,您可以将then
插入到链中,为每个承诺进行控制台更新,并让它返回它收到的相同值。
实际上,查看您的代码,您甚至不必这样做,因为您已经在使用每个 URL 的 then
处理程序来解析 JSON。只需添加:
const rp = require('request-promise');
//urlsArray is a 5000+ array of urls
let completed = 0; // ***
Promise.map(urlsArray, url =>
return rp(url)
.then(results =>
const parsed = JSON.parse(results);
++completed; // ***
console.log(`Completed: $completed`); // ***
return parsed;
).catch(err => log(error););
).then(resultsArray =>
log(resultsArray); // print out results
).catch(err =>
log(error);
);
(请注意,我在说请求完成之前解析 JSON,以防 JSON 无效并抛出。)
但是,如果您还没有按照承诺进行活动,则可以轻松插入 then
处理程序。这是一个这样做的例子(使用原生承诺,但它与 Bluebird 相同):
const data = [1, 2, 3, 4, 5];
function withoutReportingProgress()
return Promise.all(
data.map(value => new Promise(resolve =>
setTimeout(_ =>
resolve(value);
, Math.random() * 500);
))
);
function withReportingProgress()
let completed = 0; // ***
return Promise.all(
data.map(value => new Promise(resolve =>
setTimeout(_ =>
resolve(value);
, Math.random() * 500);
)
.then(value => // ***
++completed; // ***
console.log(`Completed: $completed`); // ***
return value; // ***
)) // ***
);
console.log("Starting without...");
withoutReportingProgress()
.then(_ =>
console.log("Done without");
console.log("Starting with");
withReportingProgress()
.then(_ =>
console.log("Done with");
);
);
.as-console-wrapper
max-height: 100% !important;
【讨论】:
以上是关于Promise.map() 进度指示器的主要内容,如果未能解决你的问题,请参考以下文章