2013-08-18 2 views
-2

EDIT: Я хотел бы, чтобы одна функция вызывалась и выполнялась через одну секунду последнего события keyup.Функция только выполняется с задержкой события keyup

Вот мой код: http://jsfiddle.net/gKkAQ/

JS:

function aFunction() { 
    setTimeout(function() { 
     console.log("1"); 
    }, 1000); 
} 

$(document).ready(function() { 
    $("#Input").keyup(function() { 
     aFunction(); 
    }); 
}); 

HTML:

<input type="text" id="Input"></input> 

Вы можете легко запустить JSFiddle и увидеть в консоли, что независимо от того, насколько быстро вы печатаете , функция будет выполняться независимо от ее предыдущего статуса выполнения (в этом случае setTimeout еще не выполняется за 1 секунду, но если вы продолжаете печатать, ALL func будут выполняться)

+2

Если функция не делает что-то асинхронно, это уже происходит. – Ian

+0

Если вы расскажете больше о том, что происходит внутри функции, вопрос будет более понятным. – Sergio

+0

@Sergio мой код добавлен –

ответ

3

«вы увидите функция выполняется каждый второй. Я хотел бы, чтобы это было выполнено через одну секунду последнего KeyUp действия»

setTimeout() function возвращает идентификатор, который вы можете пройти до clearTimeout(), чтобы предотвратить возникновение тайм-аута - предположим, конечно, что вы вызываете clearTimeout() до истечения времени.

var timeoutId; 
function aFunction() { 
    clearTimeout(timeoutId); 
    timeoutId = setTimeout(function() { 
     console.log("1"); 
    }, 1000); 
} 

$(document).ready(function() { 
    $("#Input").keyup(function() { 
     aFunction(); 
    }); 
}); 

Там нет никакого вреда в призыве clearTimeout() с идентификатором тайм-аута, который сделал уже произошло, в этом случае это не имеет никакого эффекта.

Таким образом, приведенный выше код очищает предыдущий таймаут (если он есть), а затем создает новый, с тем, что анонимная функция с console.log() будет выполняться только 1000 мс после того, как пользователь перестанет печатать. Если пользователь снова набирает текст после ожидания более 1000 мс, который остановит очередной тайм-аут.

+1

Демонстрация этого: http://jsfiddle.net/yv33M/ – Ian

+1

Спасибо @ Я, вы спасли мне немного усилий. – nnnnnn

+0

+1 Это работает для меня. Хорошо, тогда я искал, чтобы поместить задержку во время события keyup перед вызовом функции. Я получил это: http://stackoverflow.com/questions/1909441/jquery-keyup-delay –

0

ПРИМЕЧАНИЕ: ЭТО ОТВЕТ ОТНОСИТСЯ К НАЧАЛЬНОМУ, ОЧЕНЬ ОБЩЕМУ ВОПРОСУ, ПЕРЕД ИСПОЛНЕНИЕМ, ЧТОБЫ ПОДТВЕРДИТЬ ЭКСТРЕННУЮ РЕДАКТИРОВКУ И ПРЕВРАЩАЕТСЯ В ОЧЕНЬ КОНКРЕТНО.

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

Ближайшая альтернатива «управлению» - это начать с проверки значения глобальной переменной «счетчик активации». Если он равен 0, немедленно увеличивайте его и продолжайте выполнение. Уменьшите его при выходе.

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

Вы можете попытаться задать два раза для переменной, как:

if(activationCounter <= 0) { 
    if(activationCounter <= 0) { 
     activationCounter++; 
     // Execution 
     activationCounter--; 
    } 
} 

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

+0

Действительно, JavaScript не имеет средств для обеспечения безопасности потоков. Это можно сделать безопасно, однако, используя технику в «Совместных последовательных процессах» Дейкстры, найденную в любом учебнике операционных систем. Я не предлагаю вам реализовать алгоритм Дейкстры: просто используйте его для справки, но потратите большую часть своих усилий на пересмотр своего подхода, чтобы такие настройки не нужны. – alexsh

+0

Dijkstra признает необходимость в примитивах synchonization. Если у вас нет примитивов, то вы ничего не можете сделать (но бросаете кости). Один из простейших примитивов синхронизации - 'test and set' или' test and increment'. Это выглядит как 'if (var ++ == 0)'. Мы могли бы сказать: «О, но большинство языков поддерживает это». Проблема в том, что мы бы забыли маленькую букву: тест и приращение ** должны происходить как единая, неделимая, бесперебойная операция. «Быстрая преемственность» может работать большую часть времени, но это не настоящее решение. –

+0

wow..это кажется другим вопросом все вместе. –