2016-07-30 2 views
1

Я делаю Node.js игру, и мой мое обновление данных клиента/рендеринг логика реализована следующим образом:Блокировки при обновлении и сделать

var rendering = false; 
    var waiting_for_data = true; 
    var data_update = false; 

    socket.on('update', function(data){ 

     if(rendering)console.log("rendering"); 

     data_update = true; 
     game_data = data; 
     data_update = false; 

     if(waiting_for_data){ 
     waiting_for_data = false; 
     render(); 
     } 


    }); 

    window.requestAnimFrame = (function(){ 
      return window.requestAnimationFrame  || 
        window.webkitRequestAnimationFrame || 
        window.mozRequestAnimationFrame || 
        window.oRequestAnimationFrame  || 
        window.msRequestAnimationFrame  || 
        function(/* function */ callback, /* DOMElement */ element){ 
        window.setTimeout(callback, 1000/60); 
        }; 
    })(); 


    function render(){ 


     while(data_update){ 
     console.log("waiting" + data_update); 
     } 

     if(game_data == null)console.log(game_data); 

     rendering = true; 
     //mapa.draw(context, game_data.player_position); 
     renderer.draw(game_data); 
     rendering = false; 

     window.requestAnimFrame(render); 
    } 

    } 

И я могу видеть экран мигает со случайным положением мои элементы каждые несколько секунд. Когда i console.log данные и позиция объекта, они выглядят отлично. Должен ли я использовать какие-то замки или что-то еще? Является ли мой рендеринг var и data_update var безопасным для обновления данных. Еще одна вещь: сервер выпускает «обновление» 60 раз в секунду.

+0

Это ваше намерение запустить новый рендерер при каждом обновлении сокета. Функция рендеринга после запуска будет продолжена из-за 'requestAnimFrame', В следующем обновлении сокета вы снова вызываете рендеринг и начинаете другой рендер. Теперь у вас есть два запуска, и вы добавите еще одно обновление. Также 'while (data_update)' будет блокировать всю страницу, если визуализация когда-либо вызывается с помощью 'data_upodate = true' и устанавливает значение true для ложного файла' game_data 'не требуется. Javascript однопоточный, нет необходимости блокировать, поскольку у вас никогда не будет конфликтов одновременного доступа. – Blindman67

+0

Да, это мое намерение, и когда я визуализую в обратном вызове io 'update', всякая вещь прекрасно обрабатывается, но у меня есть несколько небольших лагов каждые несколько секунд с одним подключенным клиентским сокетом и несколькими объектами на экране. Поэтому я решил попробовать uisng requestAnimFram, потому что я читал, что это хорошо для рендеринга. Я знаю, что проблема вызвана чем-то другим, но я до сих пор не знаю, почему у меня такое странное поведение, как game_data, становится нулевым каждые несколько секунд, когда я использую requestAnimFrame, и мне просто интересно сейчас – peterSweter

ответ

0

Этот код выглядит так, будто вы пытаетесь быть потокобезопасным. Нет нужды.

JavaScript не имеет резьбы. Это всегда только одна инструкция за раз. Он работает только по одной функции за раз. Эта функция не может быть прервана, нет другого события, никакие другие данные не будут изменены до тех пор, пока текущая функция не будет завершена. Javascript является окончательным в потоковом безопасном в силу того факта, что это только последовательное выполнение. Он не может быть прерван при выполнении кода. Все события, такие как socket.on и requestAnimationFrame, должны дождаться завершения текущего выполнения до их запуска.

// var rendering = false; // not needed 
    var waiting_for_data = true; 
    // var data_update = false; // not needed 

    socket.on('update', function (data) { 
     // this will never run if render is running 
     //data_update = true; // nothing will see this 
     game_data = data; // ONLY this will ever happen between the line above and below 
     // data_update = false; // nothing will see this 

     if (waiting_for_data) { 
      waiting_for_data = false; 
      render(); 
     } 

    }); 


    function render() { 
     // if data_updata is true 
     // then the while loop will have no way to exit and nothing 
     // can change data_update while this loop is running except some code in the loop 
     // JavaScript is single threaded and can only do one thing at a time. 
     //while (data_update) { 
     // console.log("waiting" + data_update); 
     //} 

     // again single thread. Only code in this function can run NOTHING else 
     // can do anything until this function has exited all the way out 
     //rendering = true; 
     renderer.draw(game_data); 
     //rendering = false; 

     requestAnimationFrame(render); 
    } 
Смежные вопросы