1

편집 : 내가 원래 게시 한 YUI3 질문에 대한 대답을 알아 냈습니다.하지만 다른 스레드로 연결되었으므로 새 스레드를 시작하는 대신 여기에 추가 할 것입니다. 새로운 질문을 찾으려면 아래로 스크롤하십시오 (굵게 표시되어 있습니다).자바 스크립트 경쟁 조건 질문

원래 질문 : YUI 정의 내에 자바 스크립트 카운트 다운 타이머를 만드는 데 문제가 있습니다. 내 생각 엔 오브젝트 스코핑과 관련이 있습니다.

YUI({combine: true, timeout: 10000}).use("node", function (Y) { 
    var timer = new function(){}; 
    Y.augment(timer, Y.EventTarget); 
    timer.on('timer:down', function() { 
     Y.log('timer down event fired', 'event'); 
     Y.Lang.later(1000, Y, timer_trigger()); 
    }); 
    timer.on('timer:end', function() { 
     Y.log('timer end event fired', 'event'); 
    }); 

    var timer_from; 

    function startTimer(seconds){ // start a coundown from seconds to 0 
     timer_from = seconds; 
     timer_trigger(); 
    } 

    function timer_display(){ 
     var mins = Math.floor(timer_from/60); 
     var secs = timer_from - mins*60; 
     var secsDisp = secs; 
     if(secs<10){ 
      secsDisp = '0' + secs; 
     } 
     Y.one('#timer').set('innerHTML', mins + ':' + secsDisp); 
    } 

    function timer_trigger(){ 
     Y.log('timer from is: '+timer_from); 
     if(timer_from > 0){ 
      timer_from--; 
      timer_display(); 
      if(timer_from > 0){ 
       timer.fire('timer:down'); 
      } 
     } else { 
      timer.fire('timer:end'); 
     } 
    } 

    function initializePage(){ 
     startTimer(900); 
    } 


}); 

오류 내가 갖는이 내가 timer_trigger()를 호출하도록 부탁 해요 사파리 결국 내가 코드를 실행을 중지 할 것인지 나에게 묻는 것처럼 1000MS 대기하지 않는다는 것입니다 : 여기에 내 코드입니다. 페이지를로드 한 후 몇 초가 지나면 타이머는 이미 약 3, 4 분 정도입니다. 나는 또한 setTimeout을 사용해 보았지만 같은 결과가 나옵니다. 누구든지 도와 줄 수 있습니까? 나는 정말로 그것을 바르게 평가할 것이다!

편집 : 실제로 해결책을 찾아 냈습니다. 많은 시간을 거쳐야했지만 몇 가지 더 많은 Google 검색 결과가 새로운 결과/답변을 생성 할 수 있습니다. (실제로 대답은 this site입니다.)

그래서 분명히 내 코드는 경쟁 조건을 생성하고, 나는 그것을 해결하기 위해해야 ​​할 일을했을 모두가 이것이다 : 나는 경쟁 조건을 보았다

setTimeout(function(){ 
    timer_trigger(); 
}, 1000); 

하지만 내 경우에 무엇을 의미하는지 나에게 불분명 , 그리고 겉으로보기에는 사소한 변화가 내 코드를 어떻게 수정했는지. 그래서 원래의 질문에 대답했지만, 나는 대답에서 나온 질문으로 바꾸고 싶습니다.

JavaScript에서 스레딩이 작동하고 내 경쟁 조건이 발생하는 이유는 무엇이며 코드의 사소한 변경으로 인해 내가 가진 오류가 해결 된 이유는 무엇입니까?

+0

나중에 참조 할 때 내 질문에 새 스레드를 시작해야합니까? – hora

답변

2

또한

Y.Lang.later(1000, Y, timer_trigger()); 

즉시 timer_trigger을 실행하고 Y.Lang.later 반환 값을 전달 참고. 당신은 아마 의미했습니다

Y.Lang.later(1000, Y, timer_trigger); 
+0

그러면 함수의 반환 값 대신 1000ms 후에 Y.Lang.later에 함수가 전달됩니다. – hora

+0

예.timer_trigger는 위에서 작성한대로 return 문을 포함하지 않으므로 기본적으로 undefined를 반환합니다. Y.Lang.later (1000, Y, timer_trigger())의 경우 undefined가 1 초 만에 실행되는 함수로 Y.Lang.later에 전달됩니다. 이것은 으로 변환됩니다. setTimeout (function() {undefined.apply (Y);}, 1000); 런타임 오류입니다. – Luke

3

이 문제는 경쟁 조건이 아닙니다. setTimeout에 대한 추가 호출이 코드를 "수정"하는 이유는 논리 결함이 timer_trigger에 있기 때문입니다. 함수가 호출 될 때 timer_from이 1 인 경우 어떻게되는지 고려하십시오. 타이머 : 아래 또는 타이머 : 종료가 트리거되지 않습니다.

setTimeout(function(){ 
    timer_trigger(); 
}, 1000); 

timer_trigger는 다른 블록이 실행될 수 있도록 한 번 더 timer_from가 이미 0으로 설정으로 호출됩니다 :

function timer_trigger(){ 
    Y.log('timer from is: '+timer_from); 
    if(timer_from > 0){  // Since timer_from is 1, the if block is entered 
     timer_from--;  // timer_from is 0 
     timer_display(); 
     if(timer_from > 0){ // This block is not entered, but it has no matching else 
      timer.fire('timer:down'); 
     } 
    } else {     // The matching if block was entered, so this is not 
     timer.fire('timer:end'); 
    } 
} 

당신은이 코드를 추가했습니다.

+0

와우, 나는 내가 그것을 놓쳤다는 것에 충격을 받았다 ... 나의 timer_from은 결코 1에 없지만, 나는 항상 약 200 정도 멈 췄기 때문에. Luke의 대답은 실제로 timer_trigger가 1000ms를 기다리지 않았던 이유를 설명합니다. – hora