我正在测试将承诺添加到队列的代码,它们应该以非阻塞方式处理。我有一个代码可以按预期工作,但其他代码则不能,我不明白为什么。
代码未按预期工作:
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();
我期望这会将内容添加到队列中,当它们得到解决时,队列大小会减小,然后我将能够向其中添加更多内容。但在这种情况下,
then
永远不会在requestData
函数上执行。
但是,如果我将运行代码更改为:
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();
});
}
}
};
then, catch and finally
代码按预期执行,当承诺得到解决时,我可以继续向队列添加内容。为什么第一个代码不起作用但第二个代码可以?
while (true)
是一个无限循环。循环体中没有 await
,因此它永远不会挂起。这会阻塞整个应用程序,并阻止 Promise 解析(或者至少阻止它们的处理程序执行)。