найти время, оставшееся в setTimeout ()? - PullRequest
81 голосов
/ 30 июня 2010

Я пишу некоторый Javascript, который взаимодействует с библиотечным кодом, который мне не принадлежит, и не может (разумно) измениться. Он создает тайм-ауты Javascript, используемые для показа следующего вопроса в серии ограниченных по времени вопросов. Это не настоящий код, потому что он запутан вне всякой надежды. Вот что делает библиотека:

....
// setup a timeout to go to the next question based on user-supplied time
var t = questionTime * 1000
test.currentTimeout = setTimeout( showNextQuestion(questions[i+1]), t );

Я хочу поставить индикатор выполнения на экран, который заполняется до questionTime * 1000 путем опроса таймера, созданного setTimeout. Единственная проблема в том, что, похоже, нет способа сделать это. Я пропускаю функцию getTimeout? Единственная информация о тайм-аутах Javascript, которую я могу найти, относится только к созданию через setTimeout( function, time) и удалению через clearTimeout( id ).

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

var  timeleft = getTimeout( test.currentTimeout ); // I don't know how to do this
var  $bar = $('.control .bar');
while ( timeleft > 1 ) {
    $bar.width(timeleft / test.defaultQuestionTime * 1000);
}

tl; dr: Как мне найти время, оставшееся до javascript setTimeout ()?


Вот решение, которое я использую сейчас. Я просмотрел раздел библиотеки, отвечающий за тесты, и расшифровал код (ужасно и вопреки моим разрешениям).

// setup a timeout to go to the next question based on user-supplied time
var t = questionTime * 1000
test.currentTimeout = mySetTimeout( showNextQuestion(questions[i+1]), t );

и вот мой код:

// wrapper for setTimeout
function mySetTimeout( func, timeout ) {
    timeouts[ n = setTimeout( func, timeout ) ] = {
        start: new Date().getTime(),
        end: new Date().getTime() + timeout
        t: timeout
    }
    return n;
}

Это работает довольно точно в любом браузере, кроме IE 6. Даже в оригинальном iPhone, где я ожидал, что все станет асинхронным.

Ответы [ 12 ]

0 голосов
/ 04 ноября 2012

Если кто-то оглядывается на это. Я выступил с менеджером тайм-аутов и интервалов, который может дать вам время, оставшееся в тайм-ауте или интервале, а также сделать некоторые другие вещи. Я добавлю к нему, чтобы сделать его более изящным и точным, но, похоже, он работает довольно хорошо (хотя у меня есть еще несколько идей, чтобы сделать его еще более точным):

https://github.com/vhmth/Tock

0 голосов
/ 30 июня 2010

Нет, но вы можете иметь свой собственный setTimeout / setInterval для анимации в вашей функции.

Скажите, что ваш вопрос выглядит так:

function myQuestion() {
  // animate the progress bar for 1 sec
  animate( "progressbar", 1000 );

  // do the question stuff
  // ...
}

И ваша анимация будет обрабатываться этими2 функции:

function interpolate( start, end, pos ) {
  return start + ( pos * (end - start) );
}

function animate( dom, interval, delay ) {

      interval = interval || 1000;
      delay    = delay    || 10;

  var start    = Number(new Date());

  if ( typeof dom === "string" ) {
    dom = document.getElementById( dom );
  }

  function step() {

    var now     = Number(new Date()),
        elapsed = now - start,
        pos     = elapsed / interval,
        value   = ~~interpolate( 0, 500, pos ); // 0-500px (progress bar)

    dom.style.width = value + "px";

    if ( elapsed < interval )
      setTimeout( step, delay );
  }

  setTimeout( step, delay );
}
...