为什么这个承诺永远无法兑现?

问题描述 投票:0回答:1

我正在测试将承诺添加到队列的代码,它们应该以非阻塞方式处理。我有一个代码可以按预期工作,但其他代码则不能,我不明白为什么。

代码未按预期工作:

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
代码按预期执行,当承诺得到解决时,我可以继续向队列添加内容。为什么第一个代码不起作用但第二个代码可以?

javascript node.js async-await promise nonblocking
1个回答
0
投票

while (true)
是一个无限循环。循环体中没有
await
,因此它永远不会挂起。这会阻塞整个应用程序,并阻止 Promise 解析(或者至少阻止它们的处理程序执行)。

© www.soinside.com 2019 - 2024. All rights reserved.