JavaScript является однопоточным.Если вы планируете два тайм-аута на 50 мс независимо, есть вероятность, что они в конечном итоге столкнутся или приблизятся к нему и вызовут странную блокировку обработки на секунду, прежде чем они уладятся и снова смогут выйти из строя.Возможно, вам следует объединить код и создать один основной цикл, который вызывает две другие функции.Таким образом, вы можете убедиться, что они оба обрабатывают один раз каждые 50 мс.
Ваш поток выглядит примерно так:
- Process1 () -> занимает некоторое количество времени, надеюсь меньшечем 50 мс, но гарантированно будет> 0 мс.
- Process1 устанавливает для себя тайм-аут в будущем на 50 мс.2-й запуск Process1 произойдет более чем через 50 мс после его запуска в первый раз.
- Process2 () -> занимает некоторое время, превышающее 0 мс.То же, что Process1.
- Process2 устанавливает тайм-аут для себя.Применяются те же правила.2-й запуск Process2 произойдет более чем через 50 мс после его запуска в первый раз.
Если, теоретически, Process1 занимает 5 мс, а Process2 занимает 7 мс, каждые 7 запусков Process1 или 5 запусков Process2 вызовутследующий тайм-аут установлен на 50 мс в будущем, чтобы точно соответствовать запланированному времени следующего запуска другой функции.Этот тип коллизий вызовет противоречивое поведение, когда интерпретатору, который может делать только одну вещь за один раз, будет предложено обрабатывать несколько событий одновременно.
- Изменения ваших изменений в вопросе -
Вы по-прежнему устанавливаете два независимых тайм-аута на 50 мс в будущем.Все еще нет способа предотвратить их столкновение, и я все еще не совсем уверен, почему вы подходите к этому так.У вас должно быть что-то вроде этого:
function mainLoop() {
player.tick();
game.tick();
background.draw();
players.draw();
enemies.draw();
setTimeout(mainLoop, 50);
}
mainLoop()
Обратите внимание на отсутствие повторяющихся вызовов setTimeout.Все может случиться за один раз.Вы создаете коллизии в обеих версиях продемонстрированного вами кода.