#javascript
Вопрос:
Вот как выглядит мой код:
var fnInterval = setInterval(function() {
let b = true
if (b) {
console.log("hi")
} else {
console.log("bye")
}
b = !b
}, 1000);
clearTimeout(fnInterval, 10000)
Я новичок в JavaScript, и моя цель здесь-регистрировать сообщение в консоли каждые 1 секунду общей продолжительностью 10 секунд, но в течение каждого интервала я хочу, чтобы мое сообщение переключалось между «привет» и «пока» . Как я могу это сделать? (на данный момент он отображает значение логического значения по умолчанию и не изменяется позже)
Комментарии:
1. Лучше всего использовать анимационные кадры.
Ответ №1:
Переместите переменную флага из функции:
let b = true;
const fnInterval = setInterval(function() {
if (b) {
console.log("hi");
} else {
console.log("bye");
}
b = !b
}, 1000);
Чтобы остановить таймер через 10000 миллисекунд, оберните вызов clearInterval
в setTimeout
:
setTimeout(() => clearInterval(fnInterval), 10000);
Между тем, обратите внимание, что возвращаемое значение setInterval
-это не функция, а число, поэтому его вызов может ввести в заблуждение fnInterval
.
Ответ №2:
Прежде всего, объявите let b = true
вне функции обратного вызова. В противном случае он повторно инициализируется при каждом вызове.
Во-вторых, 10000 в clearTimeout(fnInterval, 10000)
не является допустимым параметром. clearTimeout(timeoutId)
принимает только первый параметр и немедленно удаляет время ожидания, переданное. Вам понадобится a setTimeout
, чтобы запустить это через 10 секунд, если это ваша цель. Но это вызывает состояние гонки между двумя тайм-аутами-неточность может означать, что вы пропустите некоторые журналы или получите дополнительные журналы.
Использование счетчика-это одно из решений, как показывают другие ответы, но обычно, когда я использую сложную синхронизацию setInterval
, для которой требуется очистить ее после некоторого количества итераций, я перестраиваюсь на общую обещанную sleep
функцию на основе setTimeout
. Это делает вызывающий код намного чище (без обратных вызовов) и позволяет избежать возни с clearTimeout
ним .
Вместо логического значения для переключения флага туда и обратно между двумя сообщениями лучшим решением является использование массива и модуль текущего индекса по длине массива сообщений. Это значительно облегчает добавление большего количества элементов для циклического просмотра, а код легче понять, поскольку состояние неявно указано в счетчике.
const sleep = ms => new Promise(res => setInterval(res, ms));
(async () => {
const messages = ["hi", "bye"];
for (let i = 0; i < 10; i ) {
console.log(messages[i%messages.length]);
await sleep(1000);
}
})();
Ответ №3:
setInterval()
это clearInterval()
не останавливает clearTimeout()
. Подробности прокомментированы в приведенном ниже коде.
// Define a counter
let i = 0;
// Define interval function
const fnCount = setInterval(fnSwitch, 1000);
function fnSwitch() {
// Increment counter
i ;
// if counter / 2 is 0 log 'HI'
if (i % 2 === 0) {
console.log(i ' HI');
// Otherwise log 'BYE'
} else {
console.log(i ' BYE');
}
// If counter is 10 or greater run fnStop()
if (i >= 10) {
fnStop();
}
};
function fnStop() {
// Stop the interval function fnCount()
clearInterval(fnCount);
};