2014-08-20 6 views
0

Код ниже позволяет мне иметь массив с набором чисел, таких как «thearray = [2,8,9]» и пропустить этот массив, а для каждого элемента номера в массиве, например «2,8», 9 ", код вызывает функцию количество раз, равное текущему номеру элемента в массиве. Поэтому, если текущий номер позиции равен 2, функция вызывается дважды.Как я могу получить этот код, чтобы сделать последовательность очевидной?

После набора вызовов происходит пауза, а затем функция снова вызывается количеством раз, равным текущему числу в массиве и т. Д. Другими словами, по мере того, как массив проходит цикл, текущий номер элемента равен 2, функция с именем «функция» будет вызываться дважды, тогда есть пауза, а функция «функция» снова называется количеством раз, равным следующему числу в массиве.

В моем случае «функция» просто отображает сообщение в поле предупреждения дважды, за которым следует пауза, затем 8 раз, за ​​которым следует пауза, затем 9 раз, за ​​которой следует пауза и т. Д. Конечно, Я получаю сообщения в последовательности, потому что я должен выбрать ok, прежде чем я увижу следующее предупреждающее сообщение. Проблема в том, что я не могу заставить вызовы «функции» появляться последовательно, например, когда код, который должен быть выполнен в «функции», отображает окно предупреждения, когда другой код, такой как добавление элемента li с данными в ul, находится внутри эта функция.

Это как если бы два вызова выполнялись сразу, тогда 8 вызовов выполняются сразу и т. Д. Даже если это может быть не так, это происходит так быстро, похоже, что это так. Я хотел бы замедлить его. Таким образом, если код внутри «функции» был кодом, который будет добавлять информацию к элементу li, вместо того, чтобы просто быстро видеть добавленную информацию, когда последовательность вызовов не заметна, я хотел бы, чтобы там была задержка, так что когда li-элементы добавляются, последовательность более очевидна, а не быстрее, когда трудно увидеть последовательность.

Вот код:

function runArray(arr, fn) { 
// initialize array index - can't use for loop here with async 
var index = 0; 

function next() { 
    var cnt = +arr[index]; 
    for (var i = 0; i < cnt; i++) { 
     fn(index, cnt); 
    } 
    // increment array index and see if there's more to do 
    ++index; 
    if (index < arr.length) { 
     setTimeout(next, 400); 
    } 
} 
// start the whole process if the array isn't empty 
if (arr.length) { 
    next(); 
} 
} 

runArray(thearray, shakeit); 

и вот jsfiddle демонстрирует журнал быстрого добавления информации. Я хочу замедлить его, чтобы информация была добавлена ​​достаточно медленно, чтобы было очевидно, что есть последовательность.

http://jsfiddle.net/jfriend00/Loycmb3b/

ответ

1

То, что вы хотите сделать, по сути, это вставить задержку между выполнений цикла for. Единственный разумный способ введения задержки в JavaScript - использовать setTimeout и setInterval, так что с этим вам нужно работать.

Следующая мысль состоит в том, что, поскольку каждая итерация цикла должна быть реализована как обратный вызов setTimeout и друзьям, логика, которая перемещается к следующему элементу массива после каждого цикла, обязательно будет частью этого - вы можете 't перейти к следующему элементу до завершения цикла.

Но логика, которая переходит к следующему элементу, уже находится внутри next, и мы уже установили, что next должен установить обратный вызов. Таким образом, next собирается запланировать обратный вызов, и обратный вызов также планируется запланировать next - другого выхода нет.

Поэтому:

function runArray(arr, fn, delay) { 
    var index = 0; 
    var cnt = 0; 
    var i = 0; 

    // Called once for each array element  
    function next() { 
     if (index >= arr.length) { 
      return; 
     } 

     cnt = +arr[index]; 
     i = 0; 
     loop(); 
    } 

    // Represents a single iteration of what was previously a for loop 
    // Will either schedule the next iteration or move to the next element 
    function loop() { 
     if (i < cnt) { 
      fn(index, i++); 
      setTimeout(loop, delay); // delay before next iteration 
     } 
     else { 
      ++index; 
      setTimeout(next, delay); // delay before moving to next element 
     } 
    } 

    if (arr.length) { 
     next(); 
    } 
} 

Я все тот же delay как между «итераций цикла» и между концом цикла и началом следующего, но это может быть легко изменена.

See it in action.

+0

Ах, простое решение. Спасибо. Мой мозг слишком устал, чтобы понять это. – Brandon

0

Я может или не может понять, что вы пытаетесь сделать, но этот кусок кода здесь

runArray(theArray, theFunction, 400); 

вы выполняете theArray и theFunction произойти через 400 мс, 1000 является один второй, так что если вы хотите, чтобы это была более существенная пауза, увеличившись на 400, здесь я увеличил ее до 4000 (4 секунды), и пауза стала намного более заметной.

http://jsfiddle.net/Loycmb3b/7/

Смежные вопросы