2013-05-05 2 views
-1

나는 다음과 같은 시나리오가 : 방지 다시 실행에서 코드가 완료되기 전에

$('button').on('click',function(){ 

    // Run AJAX commonds (May take some time); 

}); 

그래서 사용자가 버튼을 여러 번 클릭하면, 그가 ajax 요청을 많이 수행 할 수 있습니다.

이 문제를 해결하는 논리적 인 방법은 사용하는 것입니다

var finished = true; 
$('button').on('click',function(){ 
    if(finished == true){ 
     finished = false; 
     .... 
     finished = true; 
    } 

그러나 모든 기능에 전역 변수를 추가하는 것은 이상한 것 같다? 이 문제를 어떻게 해결할 수 있습니까? 나는 .off()을 들여다 보았습니다. 그러나이 완료는 이벤트를 제거합니다. one() 한 번만 실행하십시오. 여러 번 실행하지 않아도됩니다. 어쩌면이 기능을 처리하기위한 간단한 플러그인을 작성하는 것일 수도 있습니다. 그 반복.

답변

0

데이터를 추가하거나 요소에 클래스를 추가하여 처리 중임을 나타낼 수 있습니다. 그런 다음 작업이 완료되면 해당 데이터/클래스 이름을 제거하십시오.

$('button').on('click',function(){ 

    var self = $(this); 
    var processing = self.data('processing'); 

    if(!processing){ //if not processing 

    self.data('processing',true); //flag as processing 

    //do stuff 
    $.ajax({...}).done(function(responseData){ 

     //when done, unflag 
     self.data('processing',false); 
    }); 
    } 
}); 
+0

.css()/attr()이 실행되기 전에 사용자가 버튼을 두 번 클릭 할 수 있으므로 이는 바람직하지 않은 방법입니다. No. – Kivylius

+1

@Jessica 그 이유는 ** 당신이 **하기 전에 ** 당신이 뭔가를 확인하는 이유입니다. 게다가, 이것은 글로벌 플래그 접근 방식과 비슷하지만 글로벌 플래그를 사용하지 않습니다. – Joseph

+1

아니요 -이 방법은 사용하지 않지만 JS가 단일 스레드이므로 JS가 비동기 Ajax 호출이 시작되기 전에 실행할 수 없습니다. 자세한 내용은 [이 페이지] (http://ejohn.org/blog/how-javascript-timers-work/)를 참조하십시오. – Basic

0

요청이 활성화되어있을 때 버튼을 비활성화 할 수 있습니다.

$('button').click(function() { 
    //or in the ajax beforeSend function 
    $(this).prop('disabled', true); 
    $.ajax({ 
     ... 
     //or directly after the user clicked the button 
     beforeSend: function() { 
      $('button').prop('disabled', true); 
     }, 
     ... 
     //complete or success callback 
     complete: function() { 
      $('button').prop('disabled', false); 
     } 
    }); 
}); 

그러나이 방법을 사용하면 더 이상 클릭 할 수없는 버튼을 정의해야합니다. 모든 버튼을 비활성화하지 않는 한. 이것을 테스트하기 위해 working example (jsfiddle)을 생성했습니다. (AJAX가 완료된 후 AJAX가 완료된 후 1 초 지연 됨) 비활성화 된 버튼을 알 수 있도록

Timeout을 사용하면 또 다른 옵션이 될 수 있으므로 사용자가 버튼을 반복해서 누르면 AJAX 호출이 실행되지 않습니다. AJAX 호출이 시간 초과보다 오래 걸리면 문제가 여전히 존재합니다.

var timer;  
$('button').on('click', function() { 
    clearTimeout(timer); 
    timer = setTimeout(function() { 
     // Run AJAX commonds (May take some time); 
    }, 500); 

}); 
+0

나는 사용할 수 없지만 타이머는 사용하지 않을 것이다.1 초 간격으로 버튼을 클릭하면 계속 실행됩니다. – Joseph

+0

예. 그것은 내 마음에 온 아이디어였습니다. – SirDerpington

0

.on().off() 방법을 배울 수있는 간단한 방법 : http://jsbin.com/oguwux/1/edit

HTML :

<button id="btn">AJAX REQUEST</button> 

jQuery를 :

function ajaxCall(){ 

    $(this).off('click'); 
    $(this).text('Processing...'); // test only 

    setTimeout(function(){ // (example.) do your AJAX call instead 
    // ON SUCCESS : 
    $('#btn').text('AJAX REQUEST'); 
    $('#btn').on('click', ajaxCall); 
    },2000); 

} 

$('#btn').on('click', ajaxCall); 
0

어떻게 이런 일에 대해 : (안된) :

var InProgress = Array(); 
function OneAtATime($jQueryAjax) { 
    var Id = arguments.callee.toString().match(/function\s+([^\s\(]+)/) 
    InProgress.push(Id) 

    for(var i=0; i<32; i++) 
     result += Math.floor(Math.random()*16).toString(16).toUpperCase(); 
     return result 
    } 

    CallBacks = { 
      success: function(x,y,z){$jQueryAjax.success(x,y,z);Remove(Id);, 
      error: function(x,y,z){$jQueryAjax.error(x,y,z);Remove(Id);, 
      fail: function(x,y,z){$jQueryAjax.fail(x,y,z);Remove(Id); 
     } 
} 

function Remove(Id) { 
    InProgress.splice(InProgress.indexOf(Id),1); 
} 

샘플 사용법 :

다른 답변에 대한 의견에서 언급 한 바와 같이
OneAtATime({ 
    /* Usual jQuery.ajax properties */ 
    url: '/Callback'; 
    success: function(data, status, xhhr) { 
     alert('success'); 
    } 

}); 

자바 스크립트가 단일 스레드이기 때문에, 경쟁 조건의 기회가 없습니다.

관련 문제