setTimeout не вызывает обратный вызов для прерывания цикла

1

У меня есть шахматная программа, которая ищет ходы, используя рекурсивный алгоритм альфа-Бета (и некоторые слои поверх этого). Я хочу остановить поиск через 10 секунд (но я стараюсь с 1 секундой, пока он работает), поэтому я использую setTimeout для установки глобального флага.

  let timeOut = false;
  let i = 0;

  setTimeout(() => {
    timeOut = true;
    console.log('timeout');
    console.log('timeout');
    console.log('timeout');
    console.log('timeout');
  }, 1000);

  while (i < 1000 && timeOut === false) {
    score = mtdf(pos, i, score)
    console.log('depth:' + i + ', size: ' + tp.size());
    i++;
  }

Это конечно работает в браузере, поэтому я знаю, что инструкции console.log должны быть напечатаны в браузере, но это не так. Обратный вызов не вызывается. Помогите, пожалуйста.

Edit: добавлена функция timeOut variable, чтобы сделать ее более понятной. Кроме того, извините, забыли добавить я инициализацию (не то, что эти объявления даже имеют отношение к вопросу, так как проблема в том, что callbackTimeout даже не выполняется...)

  • 0
    Вы видите какие-либо ошибки в консоли?
  • 0
    Нет, я вижу только другие вещи, которые я вижу console.log, поэтому я знаю, что console.log работает. Как depth:1, size: 21
Теги:
settimeout

3 ответа

2
Лучший ответ

setTimeout будет запускать функцию, которую вы передаете ей:

  • По прошествии указанного времени
  • После того как минимальное время для тайм-аута прошло
  • Когда цикл событий не занят чем-то другим

... какой из последних.

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

Ваша функция будет вызываться после завершения цикла, когда JS-движок больше не занят.


Не пытайтесь прерывать свой цикл извне.

Перед тем, как войти в while цикл, записать текущее время.

Каждый раз, когда вы обходите цикл, сравнивайте текущее время с записанным временем.

Если разность больше, чем период, который вы хотите разрешить циклу, выйдите из цикла

1

Javascript однопоточный означает, что выполнение "асинхронных" операторов, таких как setTimeout, setInterval и XMLHttpRequest, попадает в очередь в одном потоке. Если что-то блокирует поток (например, цикл heavy while()), асинхронные операторы задерживаются.

См. Здесь более подробный ответ

Чтобы заставить ваш код работать, я предлагаю посмотреть временную метку

var t0 = new Date().getTime(), t1 = t0;
while(true)
{
    // do stuff here
    t1 = new Date().getTime();
    if (t1 % 100 === 0) console.log(t1); // [debug ]print something every 100ms
    if (t1 - t0 > 1000) break; // kill the loop after one second

}
0

setTimeout является asynchronous означает, что программа не будет ждать завершения setTimeout и код продолжит выполнение.

Вам нужно использовать Promise чтобы дождаться завершения setTimout чтобы ваш код правильно setTimout.

Кроме того, проблема вашего кода также заключается в объявлениях переменных, вы не объявляете переменные i и timeOut.

let timeOut = false;

new Promise((resolve) => {

  setTimeout(() => {
    timeOut = true;
    console.log('timeout');
    console.log('timeout');
    console.log('timeout');
    console.log('timeout');
    resolve();
  }, 1000);

}).then(() => {

  let i = 0;
  while (i < 1000 && timeOut === false) {
    score = mtdf(pos, i, score)
    console.log('depth:' + i + ', size: ' + tp.size());
    i++;
  }

});
  • 1
    Вы неправильно поняли вопрос. ОП пытается остановить цикл while на более чем секунду. Они не пытаются отложить начало на секунду.
  • 0
    Да, я понял. Итак, я уже упоминал в последнем абзаце, что проблема заключается в переменных.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню