我正在做一个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);
}
}
我可以看到屏幕每隔几秒闪烁一次我元素的随机位置。当我在console.log数据和对象位置时,它们看起来很好。我应该使用某种锁或别的东西吗?我的渲染var和data_update var是否可以安全地更新数据。还有一件事,服务器正在发出更新'每秒60次。
答案 0 :(得分: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);
}