2010-02-08 2 views
3
function myobj(){ 
    var gup=this; 
    this.lastindex=-1; 
    this.criticalSectionInTimer=0; 
    this.updateTimer; 

    this.start = function(l){ 
     if((typeof this.updateTimer)=="number"){ 
     clearInterval (this.updateTimer); 
     } 
     this.updateTimer=setInterval(function() {gup.getMessages();} , 30); 
    } 

    this.stop= function(){ 
     if((typeof this.updateTimer)=="number"){ 
     clearInterval (this.updateTimer); 
     } 
    } 

    this.addUpdate(i){ 
    //some code 
    } 

    this.rrrrnr=0; 

    this.getMessages = function(){ 
    if(this.criticalSection==0){ 
     this.criticalSection=1; 
     this.rrrrnr++; 
     console.log("in critical section"+this.rrrrnr); 
     var url="getmessages.php?lastindex="+this.lastindex; 
     $.getJSON(url, 
      function(data){ 
       gup.lastindex=data.lastindex; 
       $.each(data.updates, function(i,item){ 
       gup.addUpdate(item); 
       }); 
      } 
     ); 
     console.log("out critical section"+this.rrrrnr); 
     this.criticalSection=0; 
    } 
    } 

} 

var m= new myobj(); 
myobj.start(); 

위의 코드가 있습니다. 나는 주어진 시간 간격으로 업데이트를하는 메인 루프를 가지고있다. 문제는 내가 this.criticalSection 변수에 의해 구분 된 "중요한 섹션"에 들어 있다는 것을 깨달았습니다.자바 스크립트 중요 섹션 또는 세마포 문제

firebug에서 "critical section"+ index와 "out critical section"+ 올바른 순서로 색인을 얻지 만 Ajax 요청은 여전히 ​​처리 중입니다. 그러나 나는 같은 지수로 요청을 받고, 나는 정말로 그 문제를 찾을 곳을 모른다.

자바 스크립트에서 세마포어 또는 중요 섹션에 대한 빌드 인 기능이 있습니까?

답변

0

jQuery는 기본적으로 AJAX 비동기를 전송합니다. getJSON tryed 시도 :

$.ajax({ 
    dataType: 'json', 
    url: url, 
    type: 'GET', 
    async: false, 
    success: function(data){ 
       gup.lastindex=data.lastindex; 
       $.each(data.updates, function(i,item){ 
       gup.addUpdate(item); 
       }); 
}); 
+4

동기식 ajax 호출을 사용하는 것은 일반적으로 좋지 않습니다. UI가 완전히 잠겨져 요청 중에 고정되어 나타납니다. –

+0

@Jonathon UI 잠금과 동일한 문제가 있음 ( – vaske

0

매우 간단합니다.

정의상 비동기식 인 AJAX를 사용하고 있습니다. 즉, $ .getJSON을 실행하면 요청이 처리되는 동안 js가 계속 진행되고 중요한 섹션을 종료합니다. 따라서 첫 번째 요청이 완료되기 전에 getMessages를 여러 번 호출 할 수 있습니다.

getJSON 호출이 비동기가 아니며 호출이 끝날 때까지 임계 섹션 내에서 차단되도록하려는 것 같습니다. 이렇게하려면, 당신의 라인에 허위, 뭔가 비동기 속성을 설정해야합니다 자바 스크립트가 단일 스레드이기 때문에

$.ajax({ 
    dataType: 'json', 
    url: "getmessages.php?lastindex="+this.lastindex, 
    type: 'GET', 
    async: false, 
    success: function(data){ 
     gup.lastindex=data.lastindex; 
     $.each(data.updates, function(i,item){ 
      gup.addUpdate(item); 
     }); 
}); 
+0

) 동기식 ajax 호출을 사용하는 것은 일반적으로 좋지 않은 선택이며, UI가 완전히 잠겨져 요청 중에 고정되어 나타납니다. –

1

이 세마포 또는 중요한 부분이 아니다. 아약스 호출은 비동기식이므로 요청을 시작한 다음 행복하게 계속 진행하고 중요한 섹션을 벗어납니다. 다른 사람들이 언급했듯이 간단한 해결책은 요청을 동기식으로 만드는 것이지만 이것은 아약스의 목적을 상쇄합니다.

코드를 보면 일정한 간격으로 업데이트를받는 것처럼 보입니다. 이 경우 ajax 요청의 콜백에서 다음 업데이트를 예약하지 않으시겠습니까?

this.getMessages = function(){ 
    var url="getmessages.php?lastindex="+this.lastindex; 
    $.getJSON(url, 
     function(data){ 
      gup.lastindex=data.lastindex; 
      $.each(data.updates, function(i,item){ 
       gup.addUpdate(item); 
      }); 
    gup.updateTimer=setTimeout(gup.getMessages, 30); 
     } 
    ); 

} 

이렇게하면 세마포어가 필요 없으며 JavaScript의 이벤트 중심 특성에 더 가깝습니다. 단점은 업데이트가 정확히 간격으로 완료되지 않는다는 것입니다. 또한 30 밀리 초가 매우 짧은 간격으로 보입니다.