2014-09-05 1 views
1

저는 AngularJS를 사용하여 웹 양식을 만들고 있습니다. 이 양식에는 세 가지 버튼이 포함되어 있습니다.이 버튼을 클릭하면 정렬되지 않은 목록의 목록 항목을 세 가지 방식으로 정렬합니다. 첫 번째 메서드 호출이 아직 실행 중일 때 이러한 3 개의 단추 중 다른 하나를 클릭하는 동안 정렬되지 않은 목록을 엉망으로 만드는 경쟁 조건이 발생하는 반면 지연된 스파이크 동안 이상한 동작을 관찰했습니다. 이를 방지하기 위해, 나는 그들의 onClick 함수 중 하나가 실행되고있는 기간 동안이 3 개의 버튼을 각각 비활성으로 만들려고합니다.클릭 한 후 HTML 버튼을 사용하지 않도록 설정하는 가장 빠른 방법은 무엇입니까?

이 픽스를 실제로 한계에 맞추기 위해이 단추 중 두 개를 번갈아 반복적으로 클릭하도록 설계된 자동 테스트가 실행되었습니다. 그 아이디어는 초인적 인 속도로 두 개의 버튼을 클릭하는 테스트 소프트웨어로도 첫 번째 버튼의 메소드 호출이 진행되는 동안 두 번째 버튼을 클릭 할 수 없다는 것입니다.

각 단추의 ng-disabled 속성을 사용하여 해당 메서드의 시작과 끝에서 각 메서드가 true와 false로 토글되는 범위 수준 변수에 연결되어 수동으로 비활성화 각 기능의 시작과 끝 부분에있는 버튼을 클릭합니다. 그런데 각각의 경우에 테스트는 경쟁 조건이 여전히 트리거되고 있다고보고합니다.

메서드 호출의 맨 처음에이 단추를 수동으로 비활성화한다는 것을 고려하면이 정도면 충분하지 않습니다. 누구든지 클릭 한 후 버튼을 비활성화 할 수있는 가장 빠른 시점을 알고 있습니까?

답변

1

정리 :

당신이 겪고있는 문제를 효과적으로 실행되는 스크립트가 클릭 큐이다.

: 당신이 handler1에서

입니다 무엇을, 그래서

이벤트 처리기 한이 실행되는 브라우저 창에 응답하지 않는,하지만 클릭 촬영은 계속하고 즉시 핸들러가 수행 될 때 처리

  • 해제 단추 2
  • 버튼 사용 모든 처리를 수행
  • 2

그 이후에만 이벤트 처리 중에 클릭 한 경우에도 클릭이 처리됩니다. 이 시점에서 button2가 활성화되었으므로 handler2도 실행됩니다.

증명 : HTML의 조각으로

, 당신은 그것을 확인할 수 있습니다

<button id="test1" onclick="window.test1();">Test1</button> 
<button id="test2" onclick="window.test2();">Test2</button> 

그리고 스크립트를

window.test1 = function() 
{ 
    document.getElementById('test2').disabled = true; 
    for (var i=0; i<1000000000; i++); 
    document.getElementById('test2').disabled = false; 
    alert('Test1 done'); // Notice: Alert after enabling button 2. 
} 

window.test2 = function() 
{ 
    document.getElementById('test1').disabled = true; 
    for (var i=0; i<1000000000; i++); 
    alert('Test2 done'); // Notice: Alert before re-enabling button 1. 
    document.getElementById('test1').disabled = false; 
} 

두 개의 버튼, 그들 각각의 유사한 실행됩니다 , 시간이 많이 걸리는 스크립트. 루프가 실행되는 동안 버튼 1을 클릭 한 다음 버튼 2를 빠르게 누르면 두 핸들러가 호출되지만 루프 중에 다른 버튼이 (시각적으로) 비활성화되지 않은 것을 볼 수 있습니다. 왜냐하면 비활성화 할 신호 클릭 이벤트와 마찬가지로 버튼도 나중에 처리됩니다.

처음 버튼 2를 누르면 (메시지 상자가 다른 버튼을 활성화하기 전에 나타남) 루프가 실행되는 동안 버튼 1이 비활성화되어 있지 않지만 메시지 상자가 표시되기 전에 비활성화되어 있음을 알 수 있습니다. 메시지 상자를 닫을 때까지 그대로 남아 있습니다.

http://jsfiddle.net/u334tz36/1/

그래서, 내가 해결하기 위해 아무것도 생각합니다. 실제로 두 이벤트 핸들러는 동시에 실행되지 않지만 서로 후에 실행되므로 아무런 문제가 없을 수도 있습니다.

해결책 : 당신은 여전히이 억세스 할수 있다고 생각하고 클릭을 자동으로 소비하려는 경우

, 당신은 타이머를 사용하여이 작업을 수행 할 수 있습니다. 다음 코드에서 단추는 처리기에서 사용할 수 없지만 1ms 후에 실행되는 제한 시간에 사용됩니다. 이렇게하면 이벤트 처리기가 완료되면 (응답 형) 창에서 모든 지연된 메시지를 처리합니다. 버튼 2는 비활성화로 표시됩니다 클릭은 장애인 버튼에 의해 소비 (폐기)하고, 1ms의 나중에 버튼을 사용할 수 있습니다 :

window.enableTest2 = function() 
{ 
    document.getElementById('test2').disabled = false; 
} 

window.test1 = function() 
{ 
    document.getElementById('test2').disabled = true; 
    for (var i=0; i<1000000000; i++); 
    setTimeout(window.enableTest2, 1); 
} 

http://jsfiddle.net/u334tz36/2/

재미있는 것은, 당신은 단지에있는 창을 통해 버튼을 클릭 할 때 전송되는 메시지를 공평하게 처리 할 수 ​​있습니다. 이렇게하려면 초가 전혀 필요하지 않습니다. 1 밀리 초이면 충분하며 적은 경우에도 할 수 있습니다. 이벤트의 순서를 변경하는 것만 필요합니다. 먼저 버튼을 비활성화하는 것과 관련된 모든 업데이트를 처리 한 다음 이벤트 처리기를 수행하십시오. setTimeout은 메시지 기반이기 때문에 동일한 업데이트 메커니즘을 사용하기 때문에 실제로는 코드를 실행하여 지연 될 수 있습니다. 따라서 기본적으로 시간 제한을 설정하면 코드가 큐 끝에있는 시간 초과에 놓이게됩니다. 주어진 지연이 아무리 짧아도 상관 없습니다. 그것은 시간의 문제가 아니며, 실행 명령의 문제입니다.

그래서 해결할 수있는 방법 일 수 있습니다.하지만 제가 말했던 것처럼 저는 생각하지 않습니다. 처음에는 문제가 생겼습니다

+0

그런 철저한 대답에 감사드립니다. 가능한 경우 더 많은 상향 회선을 제공 하겠지만, 단순히 테스트 기대치를 낮춰야 할 것입니다. – Argus9

관련 문제