I'm testing a code that adds promises to a queue and they should be processed in a non-blocking way. I have a code that works as expected but other that doesn't and I don't understand why.
Code that does not work as expected:
const axios = require('axios');
const promiseQueue = require('promise-queue');
let currentQueueSize = 0;
const maxQueueSize = 5;
// eslint-disable-next-line new-cap
const queue = new promiseQueue(maxQueueSize, maxQueueSize);
const requestData = () => {
currentQueueSize++;
queue
.add(() => axios.get('https://catfact.ninja/fact'))
.then(result => {
console.log(result.data);
})
.catch(e => {
console.log(e);
})
.finally(() => {
currentQueueSize--;
});
};
const run = async () => {
while (true) {
if (currentQueueSize <= maxQueueSize) {
console.log('current queue size ', currentQueueSize);
requestData();
}
}
};
run();
I was expecting that this would add things to the queue and when they are resolved the queue size would decrease and then I would be able to add more things to it. But in this scenario the then never gets executed on the requestData function.
However if I change the run code to this:
const run = async () => {
while (true) {
if (currentQueueSize <= maxQueueSize) {
console.log('current queue size ', currentQueueSize);
ingestData();
} else {
await new Promise((resolve, _reject) => {
const waiter = () =>
setTimeout(() => {
if (currentQueueSize <= maxQueueSize) {
console.log(`Queue size ${currentQueueSize} now under max queue size of ${maxQueueSize}, resuming...`);
resolve(true);
} else {
console.log(`Waiting for queue size to reduce, current queue size ${currentQueueSize}`);
waiter();
}
}, 1000);
waiter();
});
}
}
};
The then, catch and finally code is executed as expected and I can keep adding things to the queue when the promises are resolved. Why the first code doesn't work but the second does?
while (true)is an infinite loop. You don't have anawaitin the loop body, so it never suspends. This is blocking the entire application, and prevents the promises from resolving (or at least their handlers from executing).