Принудительное выполнение функции JavaScript setTimout через x миллисекунд - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь создать функцию тайм-аута, которая выдает ошибку в случае слишком долгого зависания функции.

У меня есть следующий код:

function go() {

  try{
    console.log('started, timeout in 2 seconds...');
    setTimeout(()=>{
      throw new Error('Timed Out!');
    }, 2000);

    while(true){
      //will run forever
    }
  }catch (e) {
    console.log('timeout function worked!');
  }
}

go();

Однако ошибка не выдается.Я думаю, это из-за того, как работает цикл обработки событий в JS, но я бы хотел, чтобы моя функция тайм-аута выполнялась через 2 секунды независимо от того, что еще происходит.Как мне этого добиться?

Ответы [ 4 ]

0 голосов
/ 14 февраля 2019

Вы не можете ничего сделать, если цикл обработки событий не может продолжаться.Но приведенный ниже код должен быть ближе к тому, что вы ищете.Если вам нужно сделать оператор while, сделайте код ниже.

function go() {
  try{
    var timeout = setTimeout(()=>{
      throw new Error('Timed Out!');
    }, 2000);

    //do stuff; it can't hog the event loop
  }catch(e){
    
  }
  clearTimeout(timeout);
  return true; //return value
}

go();
var iterations = 0;
while(condition && iterations < 10){
  //do stuff
  iterations++;
}
0 голосов
/ 14 февраля 2019

Я думаю, это потому, что вы сначала входите в бесконечный цикл и никогда не выходите из него, поэтому ваш тайм-аут никогда не сработает.

Я не знаю, чего вы пытаетесь достичь, но если вы хотите выдать ошибку, переместите цикл while в установленное время в конце.Кстати, что не имеет смысла

0 голосов
/ 14 февраля 2019

setTimeout() не работает, как вы думаете.Пока цикл пока не работает.Функция setTimeout() вызываться не будет.

Javascript не поддерживает многопоточность , поскольку это интерпретируемый язык. Многопоточность : это тип модели выполнения, которая допускает существование нескольких потоков. Подробнее

Ниже приведен пример.

function loop(){
  console.time('time');
  for(let i = 0;i<10000000;i++){
    if(i % 2000000 === 0) console.log("I am looping");
  }
  console.timeEnd('time');
  console.log("Loop finished");
}
loop();
setTimeout(() => {
  console.log("I am logged from setTimeout")
},0)
0 голосов
/ 14 февраля 2019

Я бы хотел, чтобы моя функция тайм-аута выполнялась через 2 секунды независимо от того, что еще происходит.Как мне этого добиться?

Вы не можете на самом деле.Как вы и подозревали, проблема связана с циклом событий.В вашем распоряжении только одна нить, и вы положили ее в бесконечный цикл.Поскольку вы никогда не вернетесь, цикл обработки событий не сможет запустить функцию, указанную в setTimeout.

Если вы хотите, чтобы ваш цикл while был остановлен, ваш цикл while должен быть тем, который остановит его.Возможно, что-то вроде этого:

const before = Date.now();
while (true) {
  // do stuff
  if (Date.now() - before > 2000) {
    throw new Error('Timed Out!');
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...