문제

편집하다:여기에 게시한 원래 YUI3 질문에 대한 답을 찾았지만 이로 인해 다른 질문이 생겨서 새 스레드를 시작하는 대신 여기에 추가하겠다고 생각했습니다.새 질문을 보려면 아래로 스크롤하세요(굵게 표시됨).

원래 질문:YUI 정의 내에서 JavaScript 카운트다운 타이머를 생성하는 데 몇 가지 문제가 있습니다. 제 생각에는 개체 범위 지정과 관련이 있는 것 같습니다.내 코드는 다음과 같습니다.

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);
    }


});

내가 받고 있는 오류는 내가 전화를 요청하는 것처럼 1000ms를 기다리지 않는다는 것입니다. timer_trigger() Safari는 결국 코드 실행을 중단할지 묻습니다.페이지를 로드한 후 몇 초 동안 실행하면 타이머가 이미 3, 4분 정도까지 내려갔습니다.나도 사용해봤는데 setTimeout 하지만 그것도 같은 결과를 낳는다.누구든지 도와줄 수 있나요?정말 감사하겠습니다!

편집하다:실제로 해결책을 찾았습니다. 몇 시간 동안 수많은 작업을 시도한 후에 해결되었지만 Google에서 몇 가지를 더 검색하면 여전히 새로운 결과/답변이 나올 수 있습니다. (답변은 다음에서 찾았습니다. 이 장소, 실제로).

분명히 내 코드는 경쟁 조건을 만들고 있었고 이를 해결하기 위해 해야 할 일은 다음과 같습니다.

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

경쟁 조건을 찾아봤지만 내 경우에 그것이 무엇을 의미하는지, 그리고 내 코드에 대한 사소해 보이는 변경이 내가 겪고 있는 문제를 어떻게 해결했는지는 확실하지 않습니다.그래서 원래 질문에 대한 답변이 있었지만 이것을 답변에서 발생한 질문으로 바꾸고 싶습니다.

JavaScript의 스레딩은 어떻게 작동하며 경쟁 조건의 원인은 무엇이며 코드의 사소한 변경으로 인해 발생한 오류가 수정된 이유는 무엇입니까?

도움이 되었습니까?

해결책

또한 참고하세요

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

타이머_트리거를 즉시 실행하고 반환 값을 Y.Lang.later에 전달합니다.아마 당신은 의미

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

다른 팁

문제는 경쟁 조건이 아닙니다.setTimeout에 대한 추가 호출이 코드를 "수정"하는 이유는 다음의 논리 결함 때문입니다. timer_trigger.다음과 같은 경우에는 어떤 일이 일어나는지 생각해 보십시오. timer_from 함수가 호출되면 1이 됩니다.타이머:다운이나 타이머:끝이 트리거되지 않습니다.

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');
    }
}

다음 코드를 추가했습니다.

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

이로 인해 timer_trigger 다시 한 번 전화를 걸어 timer_from 이미 0으로 설정되어 있어 else 블록이 실행될 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top