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.критические разделы javascript или проблема семафора

Из firebug я получаю сообщения «в критическом разделе» + индекс и «из критического раздела» + индекс в правильном порядке, но запрос ajax все еще обрабатывается. Но я получаю запрос с тем же индексом, и я действительно не знаю, где искать проблему.

Есть ли встроенные функции для семафоров или критических секций в javascript?

ответ

0

jQuery отправить AJAX Async по умолчанию. Принято делать getJSON try:

$.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 обычно является плохим выбором. Пользовательский интерфейс полностью заблокирован и замерзает во время запроса. –

+0

@ Jonathon Я обнаружил ту же проблему с блокировкой пользовательского интерфейса ( – vaske

0

Пробел довольно прост.

Вы используете AJAX, который по определению является асинхронным. Это означает, что вы выполняете $ .getJSON, и js продолжит работу и выйдет из критического раздела во время обработки запроса. Таким образом, несколько вызовов getMessages могут быть выполнены до завершения первых запросов.

Похоже, что вы намереваетесь использовать такой вызов getJSON NOT не быть асинхронным и блокироваться в критическом разделе до его окончания. Для этого необходимо установить свойство асинхронного ложные, то в строках:

$.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 обычно является плохим выбором. Пользовательский интерфейс полностью заблокирован и замерзет во время запроса. –

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 миллисекунд кажется чрезвычайно коротким интервалом.

Смежные вопросы