2011-11-05 5 views
31

Можно создать дубликат:
Kill Ajax requests using JavaScript using jQueryОтменить запросы AJAX в полете, используя JQuery .ajax?

Вот простой код, я работаю с:

$("#friend_search").keyup(function() { 

    if($(this).val().length > 0) { 
     obtainFriendlist($(this).val()); 
    } else { 
     obtainFriendlist(""); 
    } 

}); 

function obtainFriendlist(strseg) { 

    $.ajax({ 
     type: "GET", 
     url: "getFriendlist.php", 
     data: "search="+strseg, 
     success: function(msg){ 
     UIDisplayFriends(msg); 
     } 
    }); 
} 

По существу, если событие KeyUp обжигают до возвращения функции obtainFriendlist результат (и триггеры UIDisplayFriends (msg), мне нужно отменить запрос на рейс. Проблема, с которой я столкнулась, заключается в том, что они bui ld up, а затем внезапно функция UIDisplayFriends запускается повторно.

Большое спасибо, и советы полезно тоже

ответ

19

Возвращаемое значение $.ajax является объектом XHR, который можно назвать действия по. Для отмены функции вы могли бы сделать что-то вроде:

var xhr = $.ajax(...) 
... 
xhr.abort() 

Это может быть умным, чтобы добавить некоторый дребезг, а также, чтобы облегчить нагрузку на сервере. Следующее будет отправлять только вызов XHR только после того, как пользователь перестанет печатать на 100 мс.

var delay = 100, 
    handle = null; 

$("#friend_search").keyup(function() { 
    var that = this; 
    clearTimeout(handle); 
    handle = setTimeout(function() { 
     if($(that).val().length > 0) { 
      obtainFriendlist($(that).val()); 
     } else { 
      obtainFriendlist(""); 
     } 
    }, delay); 
}); 

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

var lastXHR, lastStrseg; 

function obtainFriendlist(strseg) { 
    // Kill the last XHR request if it still exists. 
    lastXHR && lastXHR.abort && lastXHR.abort(); 

    lastStrseg = strseg; 
    lastXHR = $.ajax({ 
     type: "GET", 
     url: "getFriendlist.php", 
     data: "search="+strseg, 
     success: function(msg){ 

     // Only display friends if the search is the last search. 
     if(lastStrseg == strseg) 
      UIDisplayFriends(msg); 
     } 
    }); 
} 
+1

Мне нравится, что вы делаете с задержкой, это приятно. Тем не менее, еще нет риска, что запросы накапливаются, если пользователь является медленным автором, запуская новый ajax-запрос с каждым нажатием клавиши? –

+1

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

+1

Отлично. спасибо, это очень информативно – TaylorMac

0

Как об использовании переменной, скажем isLoading, что вы установите верно путем использования опции beforeSend (jqXHR, параметры) для .ajax, а затем с помощью чтобы установить переменную в значение false. Затем вы просто проверяете эту переменную перед запуском другого вызова ajax?

var isLoading = false; 
$("#friend_search").keyup(function() { 

    if (!isLoading) { 
     if($(this).val().length > 0) { 
      obtainFriendlist($(this).val()); 
     } else { 
      obtainFriendlist(""); 
     } 
    } 

}); 

function obtainFriendlist(strseg) { 

    $.ajax({ 
     type: "GET", 
     url: "getFriendlist.php", 
     beforeSend: function() { isLoading = true; }, 
     data: "search="+strseg, 
     success: function(msg){ 
     UIDisplayFriends(msg); 
     }, 
     complete: function() { isLoading = false; } 
    }); 
} 
+1

Не будет ли это наоборот? Если пользователь вводит «ТЕСТ» перед возвратом XHR, нажатия клавиш для E, S и T будут игнорироваться, а ответ сервера будет только для «T». –

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