SetTimeout и setInterval в асинхронной функции - PullRequest
0 голосов
/ 18 марта 2020
   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 секунд, ответ отправляется немедленно, и я получаю сообщение об ошибке «Не удается установить заголовки после их отправки».

Вызывает ли проблема наличие setInterval и setTimeout? Пожалуйста, ведите меня.

1 Ответ

1 голос
/ 18 марта 2020

Тем не менее не следуйте желаемым логикам c, так как вы на самом деле не объяснили, как вы ожидаете, что это будет работать. Я опишу, что вы делаете, и укажу несколько fl aws в этом потоке.

  1. Вы запускаете интервал, который выполняется каждые 5 секунд.
  2. Это продолжается до тех пор, пока importStatus не станет true, но ничто в этом l oop никогда не установит importStatus, так что, похоже, оно никогда не будет удовлетворено.
  3. Вы выполняете запрос к базе данных внутри l oop, но никогда не ссылаетесь на результат запроса к базе данных. Я предполагаю, что это не может быть правдой. Опять же, в том, что вы опубликовали, не хватает некоторого кода.
  4. Затем, после 15 итераций интервала, вы также начинаете делать setTimeout() каждые 18 секунд.
  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() работают. Вряд ли вы этого хотите. Возможно, вам следует остановить setInterval(), когда вы начнете делать setTimeout()
  4. addProcess(), показывающий интерфейс обратного вызова в асинхронном стиле, но не имеющий возможности для обработки ошибок. Это действительно функция, которая не может иметь ошибок?
  5. Вы даже не ссылаетесь на data, который является результатом запроса к базе данных, поэтому запрос никогда не используется.

Редактируйте с вашего комментарий:

Это лог c, который я хочу реализовать. 1) Опрашивайте базу данных 15 раз каждые 10 секунд. 2) Даже через 1 с половиной минуты, если статус не соответствует действительности, отправьте 500 и остановите процесс.

Ну, 15 раз, 10 секунд каждый и 1-1 / 2 минуты не т все сложить. 15 раз по 10 секунд каждый будет 150 секунд, что будет 2-1 / 2 минуты. Вот реализация, которая делает 15 раз за 10 секунд. Вы можете настроить числа так, как вы хотите.

  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);
...