2010-01-05 7 views
7

사용자가 문자를 입력 할 때마다 Ajax 요청으로 검색하고 결과를 "실시간"으로 표시하는 텍스트 상자가 있습니다. 종종 사용자가 글자를 입력 할 때 사용자가 새로운 글자를 입력하는 것보다 요청을하는 데 더 많은 시간이 걸리기 때문에 첫 번째 글자가 끝나기 전에 새로운 요청이 만들어집니다. 다음 요청을하기 전에 첫 번째 프로그램이 끝나면 훨씬 더 좋습니다. 최신 요청이 끝난 경우에만 새로운 요청을하는 좋은 방법이 있습니까?Jquery ajax 요청, 최신 요청이 완료 될 때까지 기다림

이 내 jQuery 코드입니다 : 당신이 요청이 새로운 요청을하기 전에 완료되면 알 수 있도록

$("#MyTextBox").change(function() { 
    if (this.value.length > 2) { 
     $.ajax({ 
      type: "GET", 
      url: "http://www.domain.com/Service.svc/Search?keyword=" + this.value, 
      dataType: "json", 
      success: function(data) { 
       //here I have some code that shows the result for the user 
      } 
     }); 
    } 
}); 

답변

9

요청이 이미 발생했는지에 따라 참 또는 거짓을 유지할 부울을 만들 수 있습니다. 요청을 시작할 때 true로 설정하고 콜백 함수에서 false로 다시 설정하십시오.

var request_in_process = false; 
$("#MyTextBox").change(function() { 
    if (this.value.length > 2 && !request_in_process) { 
     request_in_process = true; 
     $.ajax({ 
      type: "GET", 
      url: "http://www.domain.com/Service.svc/Search?keyword=" + this.value, 
      dataType: "json", 
      success: function(data) { 
       request_in_process = false; 
       //here I have some code that shows the result for the user 
      } 
     }); 
    } 
}); 
+0

고마워요! 이것은 내가 찾고 있었던 바로 그 것이었다. 그러나 어떤 이유로 텍스트를 입력 할 때마다 글자를 입력 할 때마다 약간 버그가 있으며 각 글자가 일종의 지연으로 표시되는 것처럼 보입니다. ajax 요청은 비동기로 보내야 텍스트 상자에 영향을주지 않아야합니다. – Martin

+1

요청이 실패 할 경우'success'보다는'complete' 설정에서'request_in_progress'와 같은 정리 코드를 가진 함수를 할당하는 것이 좋습니다. –

0

당신은 ajaxComplete을 활용할 수 있습니다.

변경 사항 이벤트가 수동으로 한 번 추가 된 다음, ajax 요청이 시작될 때 언 바운드되고 ajax 요청이 완료 될 때 리 바인드되도록 bind/unbind와 결합 할 수 있습니다.

8

AJAX 요청을 중단 할 수 있습니다. 요청을 변수로 추적하고 요청을 다시 시작하기 전에 중단하십시오.

var request = $.ajax({ ... }); 
request.abort(); 

이것은 사용자 입력에 더 잘 응답한다는 장점이 있습니다. 첫 번째 요청이 시작된 이후 사용자가 더 많은 내용을 입력하면 아마도 첫 번째 결과 집합에 대해 더 이상 신경 쓰지 않을 것입니다. AJAX 요청을 중단하고 재생성하면 사용자가 더 나은 결과를 얻을 수 있습니다.

0

ceejayoz가 이미 언급 했으므로 이전 요청을 중단해야합니다. (그들이 원하는대로 입력 할 수없는 경우 사용자가 미친 것 요청을 기다리는 그리고 새로운 사람을 통해 이전 요청을 선호한다 결과가 오래된 있습니다..) 그래서 대해 : 여기

var request = null; 
//...  
$("#MyTextBox").change(function() { 
    if (this.value.length > 2) { 
     if (request && request.abort) 
      request.abort(); 
     request = $.ajax({ 
      type: "GET", 
      url: "http://www.domain.com/Service.svc/Search?keyword=" + this.value, 
      dataType: "json", 
      success: function(data) { 
      //here I have some code that shows the result for the user 
      request = null;     
     }); 
    }    
}); 
0

있어 약간 더 강력한 이행. 기본적으로 ajax 객체 (즉, 약속 객체)를 닫음으로 저장하여 후속 호출에서이 객체를 볼 수 있도록합니다. 다음 호출에서 요청 상태가 보류 중임을 확인하면 새 요청을 생성하는 대신 보류중인 요청에 콜백을 추가합니다. jQuery는 추가 된 것과 동일한 순서로 모든 콜백을 시작합니다. 그러나 동일한 발신자가 요청을 반복해서 만들려는 가능성이 있습니다. 이를 방지하기 위해 callerId 매개 변수를 추가했습니다. 이전 요청이 아직 보류 중일 때 동일한 발신자가 다시 요청한 경우 해당 요청을 무시합니다. 완성을 위해 나는 cachedValues도 추가했다. 따라서 아약스 요청이 이미 이루어진 경우 다시 만들지 않습니다.

var ajaxRequestor = function ($) { 
    "use strict"; 

    //privates 
    var cahedValues = {}; 
    var currentAjaxRequest, callers; 

    //public interface 
    return { 
     getData: function (callerId, onGet, onFail, forceRefresh) { 
      if (forceRefresh || !cahedValues.myData) { 

       //If there is a pending request, don't start new one 
       if (!currentAjaxRequest || currentAjaxRequest.state() != "pending") { 
        currentAjaxRequest = $.getJSON("data/MyData.json"); 
        callers = {}; //list of callers waiting for request 
       } 

       //if this caller is not in the list, add it and queue up its callbacks to existing request 
       if (!callers[callerId]) { 
        callers.callerId = callerId; 

        currentAjaxRequest.done(function (data, textStatus) { 
         cahedValues.myData = data; 
         onGet(data); 
        }); 

        currentAjaxRequest.fail(function (jqxhr, textStatus, error) { 
         if (!!onFail) { 
          onFail(error); 
         } 
         else throw error; 
        }); 
       } 
      } 
      else { 
       onGet(cahedValues.myData); 
      } 
     }, 

     invalidateMyData: function() { 
      delete cahedValues.myData; 
     } 
    }; 
})($); 
관련 문제