Вопрос

Я думал, что попробую быть умным и создаю свою собственную функцию ожидания (я понимаю, что есть другие способы сделать это). Так я писал:

var interval_id;
var countdowntimer = 0;

function Wait(wait_interval) {
  countdowntimer = wait_interval;

  interval_id = setInterval(function() {
    --countdowntimer <=0 ? clearInterval(interval_id) : null;
  }, 1000);

  do {} while (countdowntimer >= 0);
}

// Wait a bit: 5 secs
Wait(5);

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

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

Ясно, как-то, есть два значения Таймер обратного отсчета плавать вокруг, но почему?

РЕДАКТИРОВАТЬ

Хорошо, так что я понимаю (сейчас), что JavaScript один резьбовый. А что - - Вроде - отвечает на мой вопрос. Но, в какой момент в обработке этой единственной нити используют так называемый асинхронный вызов setinterval. на самом деле случится? Это просто между функционными звонками? Конечно, нет, как насчет функций, которые занимают много времени, чтобы выполнить?

Это было полезно?

Решение

Нет двух копий переменной, лежащей вокруг. JavaScript в веб-браузерах Однопоток (если вы не используете Новые веб-рабочие вещи). Таким образом, анонимная функция никогда не имеет возможности запустить, потому что Wait связывает переводчика.

Вы не можете использовать функции занятых ждет в JavaScript на основе браузера; Ничто другое никогда не произойдет (и они плохой идеи в большинстве других сред, даже где их возможно). Вместо этого вы должны использовать обратные вызовы. Вот минималистский переработчик этого:

var interval_id;
var countdowntimer = 0;

function Wait(wait_interval, callback) {
    countdowntimer = wait_interval;

    interval_id = setInterval(function() {
        if (--countdowntimer <=0) {
            clearInterval(interval_id);
            interval_id = 0;
            callback();
        }
    }, 1000);
}

// Wait a bit: 5 secs
Wait(5, function() {
    alert("Done waiting");
});

// Any code here happens immediately, it doesn't wait for the callback

Редактировать Отвечая на ваше следующее:

Но, в какой момент в обработке этого единственного потока есть так называемый асинхронный вызов, используя Setinterval? Это просто между функционными звонками? Конечно, нет, как насчет функций, которые занимают много времени, чтобы выполнить?

В значительной степени, да - и поэтому важно, чтобы функции не были долгостоятельными. (Технически это даже не между вызовыми функциями, в том случае, если у вас есть функция, которая вызывает три других функция, интерпретатор не может сделать что-то еще, пока работает то, когда работает то, когда работает то, когда она работает.) Переводчик по существу поддерживает очередь функций, которые необходимо выполнить. Начинается начинается, выполняя любой глобальный код (скорее как большой звонок функции). Затем, когда все происходит (события ввода пользователей, время для вызова обратного вызова, запланированного через setTimeout Достигнут и т. Д.) Переводчик толкает вызовы, которые необходимо сделать в очередь. Это всегда обрабатывает вызов на передней части очереди, и поэтому все может сложить вверх (как ваш setInterval звонки, хотя setInterval это кусочек Специальное - это не будет очередью последующего обратного вызова, если предыдущий все еще сидит в очереди, ожидая обработки). Так что думайте с точки зрения того, когда ваш код получает контроль и когда он выпускает управление (например, возвращение). Переводчик может Только Делайте другие вещи после выпускания контроля, и прежде чем он вернет его снова. И снова, на некоторых браузерах (например, например), той же нить также используется для покраски пользовательского интерфейса и такого, поэтому DOM вставки (например) не будут отображаться до тех пор, пока не выпустите контроль обратно в браузер, чтобы он мог получить с помощью своей картины.

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

// Non-functional non-event-driven pseudo-example
askTheQuestion();
answer = readTheAnswer();      // Script pauses here
doSomethingWithAnswer(answer); // This doesn't happen until we have an answer
doSomethingElse();

Это не работает в мире, управляемый событием. Вместо этого вы делаете это:

askTheQuestion();
setCallbackForQuestionAnsweredEvent(doSomethingWithAnswer);
// If we had code here, it would happen *immediately*,
// it wouldn't wait for the answer

Так, например, askTheQuestion Может накладывать div на странице с полями, предложав пользователям различные части информации с кнопкой «OK» для их щелчка, когда они закончат. setCallbackForQuestionAnswered действительно будет зацепляться click Событие на кнопке «ОК». doSomethingWithAnswer будет собирать информацию из полей, удалить или скрыть div и сделать что-нибудь с информацией.

Другие советы

Большинство реализации JavaScript Однопоток, поэтому, когда он выполняет while петля, это не пускает ничего другого выполнения, поэтому interval Никогда не работает, пока while работает, что делает бесконечный цикл.

Есть много похожих попыток создать Сон / ждать / пауза Функция в JavaScript, но поскольку большинство реализаций являются одиночными резьбой, она просто не позволяет вам делать что-либо еще во время сна (!).

Альтернативный способ сделать задержку - это написать тайм-ауты. Отказ Они могут отложить выполнение кусочки кода, но вы должны сломать его во многих функциях. Вы всегда можете встроить функции, чтобы он проще следовать (и для обмена переменными в одном контексте выполнения).

Есть также некоторые библиотеки, которые добавляют некоторые ситатические сажки на JavaScript, что делает более читаемый.

РЕДАКТИРОВАТЬ:Там пост экскавала блог Джон Стиг Сам о Как работают таймеры JavaScript. Отказ Он в значительной степени объясняет его детали. Надеюсь, поможет.

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

Есть причина, почему никто не сделал Wait до (и так много попробовали); Это просто не может быть сделано.

Вам придется приберем к тому, чтобы тормозить свою функцию в биты и расписать их с помощью SettimeOut или Setinterval.

//first part
...
setTimeout(function(){
    //next part
}, 5000/*ms*/);

В зависимости от ваших потребностей это может быть реализовано как государственный автомат.

Вместо того, чтобы использовать глобальную переменную CountDownTimer, почему бы просто не изменить атрибут Millisecond на SetintInterval? Что-то вроде:

var waitId;

function Wait(waitSeconds)
{
    waitId= setInterval(function(){clearInterval(waitId);}, waitSeconds * 1000);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top