2013-10-01 2 views
0

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

Вот код:

var tests = []; 
tests.push("$.notification('this is a test');"); 
tests.push("$.notification('this is a test', 7);"); 
tests.push("$.notification({ message: 'this is a test', code: 'warning', sticky: false });"); 
tests.push("$.diagnostic({ message: 'click OK to continue', alert: true });"); 
tests.push("$.notification.erase();"); 

// Почему это не работает? //>
функция wait (ms) { var done = false; в то время как (! Сделано) { SetTimeout (функция() { сделано = истина; }, мс) }}

Вот консоль:

16.30.6.265: : Executing test[0]: $.notification('this is a test'); 
16.30.6.266: : Executing test[1]: $.notification('this is a test', 7); 
16.30.6.266: : Executing test[2]: $.notification({ message: 'this is a test', code: 'warning', sticky: false }); 
16.30.6.266: : Executing test[3]: $.diagnostic({ message: 'click OK to continue', alert: true }); 
16.30.6.266: : Executing test[4]: $.notification.erase() 

;

Временная метка находится в мс, поэтому никакой задержки не происходит.

+0

Что это такое (функция (индекс) {...}); 'делать? Вы забыли использовать его как IEFE? Если да, для чего должен был использоваться «индекс»? – Bergi

ответ

0

Проблема в том, что setTimeout не «стек». То есть, когда вы вызываете setTimeout, за которым следует еще один setTimeout, JavaScript не выполняет первую, THEN выполняет вторую. В нем говорится: «О, эй, сделай эти два тайм-аута через некоторое время». Если это время одно и то же, то они оба будут выполняться одновременно (или в пределах микросекунд друг друга, и не должны полагаться на одно исполнение перед другим).

Существует два решения вашей проблемы. Либо вы можете каждый раз увеличивать таймаут, чтобы события происходили пошатнутым образом, или вы могли связать таймауты так, чтобы первый запускал второй, второй запускал третий и т. Д.

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

delay = 500; // half a second between messages 
for (var i = 0; i < tests.length; i++) { 
    t = tests[i]; 
    $.diagnostic('Executing test[' + i + ']: ' + t); 
    (function (index,t) { 
     setTimeout(function() { 
      eval(t); 
     }, index*delay); 
    })(i,t); 
} 

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

+0

Спасибо за ваши отзывы. Я посмотрю на это завтра. Что касается eval, я согласен, но этот код только в моем модульном методе тестирования, а не в каком-либо основном коде. –

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