Как JQueryUI Autocomplete обрабатывает асинхронные результаты? - PullRequest
2 голосов
/ 05 января 2012

У меня проблемы с пониманием того, как функция автозаполнения JQueryUI работает с повторными нажатиями клавиш, что приводит к асинхронным результатам. Мне нужно что-то с похожей функциональностью, но я не могу получить результаты автозаполнения, чтобы войти правильно. Пример:

$(document).ready(function() {
    $('#textinput').live('keyup', function() {
        $.get('bacon.php', function(data) {
             $('#holder').html(data);
        });
    });
});

Проблема в том, что при быстром наборе результаты часто возвращаются не в правильном порядке. Если я наберу слово «KEY», я могу получить результаты для «K», затем «KEY», а затем «KE», запутав содержимое #holder. Я заметил, что у автозаполнения JQueryUI нет этой проблемы, но я не могу понять, как это обрабатывает.

Ответы [ 3 ]

8 голосов
/ 05 января 2012

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

 var xhr, throttle;

 $('.autocomplete').keyup(function() {
      var $this = $(this);
      if (throttle)
         clearTimeout(throttle); // Clear the previous request
      xhr.abort(); // Abort the last XHR request
      throttle = setTimeout( function() {
          xhr = $.getJSON('autocomplete.php', { data: $this.val() }, function(data) {
              // do something with response
          });
      }, 250); // wait 250 milliseconds before running this
 });

По сути, дроссель заставляет нас ждать 250 миллисекунд перед отправкой запроса, если пользователь все еще печатает (вы можете установить это как угодно).Переменная «xhr» хранит XMLHttpRequest в переменной, и если мы получим еще одно нажатие клавиши, а ответ еще не вернулся, то мы отменяем предыдущее, следя за тем, чтобы только последний действительно возвращал ответ.

Надеюсь, это поможет.

Удачи:)

0 голосов
/ 18 апреля 2014

У меня была точно такая же проблема, и он наткнулся на прокси-шаблон , упомянутый Адди Османи.

Я думаю, это более актуально для события наблюдателя в реальном времени

$( "button" ).on( "click", function () {
    setTimeout( $.proxy( function () {
        // "this" now refers to our element as we wanted
        $( this ).addClass( "active" );
    }, this), 500);
});

Надеюсь, что поможет

0 голосов
/ 05 января 2012

Я просто работал над чем-то очень важным. Простой «отложенный» API для преобразования функции в отложенный делегат.

Function.prototype.delayed = function(ms, reset)
{
    var timeout;
    var fn = this;
    return function()
    {
        var args = arguments;
        var scope = this;
        if (reset && timeout) clearTimeout(timeout);
        timeout = setTimeout(function() { fn.apply(scope, args) }, ms);
    };
};

См. скрипка для использования в качестве образца.

В вашем случае это будет так

$(document).ready(function() {
    $('#textinput').live('keyup', (function() {
        $.get('bacon.php', function(data) {
            $('#holder').html(data);
        });
    }).delayed(300, true));
});
...