2010-02-08 41 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定界的“临界区”。javascript临界区或信号量问题

从firebug我得到的消息“在关键部分”+索引和“出关键部分”+索引在正确的顺序,但ajax请求仍在处理中。但我得到了同样索引的请求,我真的不知道该在哪里寻找问题。

JavaScript中是否有信号量或关键部分的任何buildin功能?

回答

0

jQuery默认发送AJAX异步。做getJSON的尝试:

$.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调用不是异步,并在临界区内被阻塞直到它结束。要做到这一点,你必须在该行的异步属性设置为false,东西:

$.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

有没有信号灯或关键部分,因为JavaScript是单线程的。你所做的ajax调用是异步的,所以它启动了请求,然后继续快乐地离开你的关键部分。正如其他人所提到的,一个简单的解决方案是使请求同步,但是这违背了Ajax的目的。

看着你的代码,好像你正在试图定期更新。如果是这种情况,为什么不在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毫秒似乎是一个非常短的时间间隔。