I am using p-limit package to limit the # of concurrent requests made using Promise.all.
I would like to show the progress of the total requests, and see that there is a variable limit.pendingCount in the library.
My question is how can I use that variable to report progress, when I console log that variable, it only returns a final value of 0.
(async () => {
const result = await Promise.all(promises);
// eslint-disable-next-line
console.log(limit.pendingCount);
Since you are await
-ing the Promise.all
call, all promises will be completed by the time you reach your console.log
statement.
Try checking the pending count without await
-ing the promises initially. Any code after await
-ing the promises will only be executed after all promises are completed (i.e. pending count is 0).
const numThreads = 2;
const numPromises = 4;
const pLimit = require("p-limit")
const limit = pLimit(numThreads);
const promises = new Array(numPromises).fill()
.map((n, i) => i + 1)
.map(n => limit(() => new Promise(r => {
console.log(`Started Promise ${n}`);
setTimeout(r, n * 1000);
})
.then(() => console.log(`Completed Promise ${n}`))));
trackProgress('After Promises Initiated', promises);
const result = await Promise.all(promises);
trackProgress('After Promises Awaited', promises);
/**
* Prints the state of the current pending promises until all pending promises are completed. This works only for this sample; it is not production quality.
*/
function trackProgress(label, promises) {
console.log(`[${label}] Tracking started.`);
const printProgress = () => {
if (limit.pendingCount > 0) {
console.log(`[${label}] Pending: ${limit.pendingCount} of ${promises.length}`);
setTimeout(printProgress, 1000);
}
else {
console.log(`[${label}] Tracking completed.`);
}
};
printProgress();
}
/*
* Output:
* "Started Promise 1"
* "Started Promise 2"
* "[After Promises Initiated] Tracking started."
* "[After Promises Initiated] Pending: 2 of 4"
* "Completed Promise 1"
* "Started Promise 3"
* "[After Promises Initiated] Pending: 1 of 4"
* "Completed Promise 2"
* "Started Promise 4"
* "[After Promises Initiated] Tracking completed."
* "Completed Promise 3"
* "Completed Promise 4"
* "[After Promises Awaited] Tracking started."
* "[After Promises Awaited] Tracking completed."
*/
Edit:
If you are looking to do a progress tracker, you may have better luck by adding callbacks to the end of the executed promises:
const numThreads = 2;
const numPromises = 4;
const pLimit = require("p-limit");
function executeRequests() {
const limit = pLimit(numThreads);
let numCompleted = 0;
console.log(`${100 * numCompleted / numPromises}% Complete`);
const updateNumCompleted = () => {
numCompleted++;
// TODO: Instead of console.log, update UI
console.log(`${100 * numCompleted / numPromises}% Complete`);
if (numCompleted >= numPromises) {
// TODO: Instead of console.log, update UI
console.log('All promises complete');
}
};
const promises = new Array(numPromises).fill()
.map((n, i) => i + 1)
.map(n => limit(() => new Promise(r => {
console.log(`Started Promise ${n}`);
setTimeout(r, n * 1000);
})
.then(() => {
console.log(`Completed Promise ${n}`);
updateNumCompleted();
})));
Promise.all(promises);
}
executeRequests();
/*
* Output:
* "0% Complete"
* "Started Promise 1"
* "Started Promise 2"
* "Completed Promise 1"
* "25% Complete"
* "Started Promise 3"
* "Completed Promise 2"
* "50% Complete"
* "Started Promise 4"
* "Completed Promise 3"
* "75% Complete"
* "Completed Promise 4"
* "100% Complete"
* "All promises complete"
*/