异步函数中的 SetTimeout 和 setInterval

SetTimeout and setInterval in an asynchronous function

   var processStatusCheck = setInterval(function statusCheck() {
    sequelize.query(dbQuery).then(function (data) {
       winston.info(' Status:', importStatus);
      if (importStatus ===  true) {
        winston.info('Inside', pollCount);
        clearInterval(processStatusCheck);
        addProcess(Id, function (response) {
               res.send(200)
        });
      } else {
        if(pollCount > 15){
          winston.info('It came here !!!', pollCount);
           res.sendStatus(500);      
        }else{
          winston.info('Incrementing.....');
          pollCount++;
          setTimeout(statusCheck, 18000);
        }
      }
    });
  }, 5000);

我正在尝试实现异步 Javascript 函数。我想连续查询数据库直到状态变为真,

最初调用是在 5 秒后根据 setInterval 进行的,但是一旦达到 setTimeout,它就会连续调用该函数。我希望它在 18 秒后被调用。 如果 setTimmeout 中的时间小于 5 秒,则立即发送响应,我收到 "Can't set headers after they are sent" 错误。

setInterval 和 setTimeout 是否给我带来了问题?请指导我。

仍然不要遵循所需的逻辑,因为您还没有真正解释您期望它如何工作。我将描述您在做什么,并指出该流程中的几个缺陷。

  1. 您开始每 5 秒运行一次的间隔。
  2. 一直运行到 importStatus 变为 true,但此循环中没有任何内容设置 importStatus,因此似乎永远不会满足。
  3. 您在循环内进行数据库查询,但从未引用数据库查询的结果。我认为那是不对的。同样,您发布的内容中肯定缺少一些代码。
  4. 然后,在间隔的 15 次迭代之后,您还开始每 18 秒执行一次 setTimeout()
  5. 因此,5秒间隔和18秒间隔setTimeout()都是运行。
  6. 然后,在 15 次迭代之后,您执行 res.sendStatus(500),但永远不要停止 setInterval(),它保持 运行 并在每次触发时一直尝试执行 res.sendStatus(500)

问题总结:

  1. 此代码中的任何内容都不会对 importStatus 做任何事情,因此它永远不会 true 基于此代码。我假设您的真实代码一定与您在此处显示的不同。
  2. 如果 importStatus 永远不会是 true(见上一点),那么你永远不会停止间隔 - 它永远运行。您需要停止间隔计时器,可能在几个地方。当然,当你做 res.sendStatus(500) 时停止它,当你开始做 setTimeout() 时也可能停止它。
  3. 经过 15 次间隔迭代后,您开始进行 setTimeout() 设置,持续 18 秒。所以,现在区间和 setTimeout() 都是 运行。你似乎不太可能想要那个。也许您应该在开始执行 setTimeout()
  4. 时停止 setInterval()
  5. addProcess()显示了一个异步风格的回调接口,但是没有错误处理的机会。真的是可以没有错误的函数吗?
  6. 您甚至从未参考过 data,这是数据库查询结果,因此从未使用过该查询。

根据您的评论进行编辑:

This is the logic I want to implement. 1) Poll the Database for 15 times , every 10 seconds . 2) Even after 1 and half minutes, if the status is not true, send 500 and stop the process.

好吧,这 15 次,每次 10 秒和 1-1/2 分钟并不全部加起来。 10 秒 15 次,每次 150 秒,即 2-1/2 分钟。这是一个在 10 秒内执行 15 次的实现。您可以根据需要调整数字。

  let pollCount = 0;
  const processStatusCheck = setInterval(function statusCheck() {
    sequelize.query(dbQuery).then(function (data) {
       if (someCondition) {
            clearInterval(processStatusCheck);
            addProcess(Id, function (response) {
               res.send(200)
            });
       } else {
            ++pollCount;
            if (pollCount > 15) {
                clearInterval(processStatusCheck);
                res.sendStatus(500);
            }
       }
  }, 10 * 1000);