2013-06-14 3 views
1

Я строю библиотеку JavaScript. Я работать над функцией задержки, которая работает следующим образом:Функция задержки Javascript

function delay(ms) { 
    var start = new Date().getTime(); 
    for (var i = 0; i < 1e7; i++) { 
     if ((new Date().getTime() - start) > ms){ 
      break; 
     } 
    } 
} 

Идея заключается в том, что я могу сделать что-то вроде этого:

window.onload = function() { 
    delay(5000); //this function will act 5 seconds after the page loads 
    document.getElementById('Header').innerHTML = 'Welcome'; 
}; 

Задержка работает отлично, но он останавливает все Javascript на а не просто задерживает функцию window.onload.

Кто-нибудь знает, что я могу сделать?

+1

Не делайте этого! Никогда не зацикливайтесь, чтобы ждать условия. Используйте setTimeout и очередь. –

+5

Это ужасный способ сделать что-то, боюсь. Вам нужно заглянуть в 'setTimeout()'. – Pointy

+0

@ Pointy - Хорошо, я буду –

ответ

4

Ваш вопрос (и ответы на Patrick D's answer) есть, я думаю, основанный на недоразумении.

Невозможно реализовать код, который будет делать то, что вы хотите.

Среда JavaScript является однопоточной. (Давайте игнорируем веб-работников на данный момент.) Это означает, что каждая строка выполняется после первой.

Если у вас есть функция, которая занимает этот (один и тот же) поток в течение 5 секунд, больше ничего не будет запускаться в течение этих 5 секунд. Это так просто.

Способ, которым мы обходим это в мире JavaScript, - использовать асинхронное программирование, которое использует обратные вызовы. Функция setTimeout - это правильный способ решить эту проблему.

Теперь вы можете сделать это. Скажем, вам нужна функция, которая, учитывая некоторую функцию fn, возвращает новую функцию, которая выполняет fn после установленной задержки. Вы могли это реализовать:

Function.prototype.delay = function(ms) { 
    var fn = this; 
    return function() { 
     setTimeout(fn, ms); 
    }; 
}; 

Тогда вы могли бы гипотетически написать код вроде следующего:

function foo() { 
    // something or other 
} 

var fooDelayed = foo.delay(5000); 

// Now this line will execute foo after 5 seconds. 
fooDelayed(); 

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

См. this jsFiddle, демонстрируя идею.

+0

Хорошо, спасибо. Вы должны отметить это как свой ответ. –

+0

Благодарим вас за то, что вы хорошо объяснили свой ответ, вы полностью ответили на мой вопрос. –

6

Используйте setTimeout вместо вашего метода задержки. Он не будет блокировать пользовательский интерфейс и намного чище.

setTimeout(function() { 
    document.getElementById('Header').innerHTML = 'Welcome'; 
}, 5000); 
+0

Ну, это не решает проблему OP: он хочет функцию задержки ... –

+1

Это выполнит его функцию после 5-секундной задержки. Чего не хватает? –

+0

OP говорит, что он хочет построить библиотеку с функцией задержки ... –

2

Если вы действительно хотите построить функцию вокруг setTimeout(), вы свободны сделать так:

не
function delay(ms, callback) { 
    setTimeout(callback, ms); 
} 

Там абсолютно никакого другого способа для задержки действия или выполнение блока кода без блокирующий механизм.

А поскольку асинхронно действует setTimeout(), вы всегда должны предоставить функцию обратного вызова!

+0

Не могли бы вы привести пример того, как это будет использоваться. –

+0

Это решение совпадает с моим ответом, оно просто абстрагирует один параметр. Вам все равно придется использовать обратные вызовы в любом сценарии. Это точно то же самое. –

+0

@PatrickD Абсолютно! Я не могу понять причины OP для необходимости этой избыточной функции. +1 для вас кстати. – ComFreek

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