我正在尝试同时向JSON API发送许多GET请求。我在Node.js中使用Bluebird promises,并使用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()会等到完成所有操作。当地图通过请求时,如何向控制台打印某种进度指示器(如百分比)?
我在每次请求后都尝试了log(results);
,但这只是向控制台打印了5000个东西,这不是很方便。我更喜欢一个百分比,或一个显示大约完成了多少的数字。
答案 0 :(得分:2)
请记住,承诺链只是:链条。因此,您可以为链中的每个承诺插入一个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无效并抛出。)
但是,如果您尚未执行per-promise活动,则可以轻松插入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;
}