I`m trying to make a small game on node.js + socket.io + mysql.
The node.js server reads the database info about the field and items on it(40×40). This info it keeps itself, and gives it on request.
The problem is that if you simply send a request, the info comes. But if you try to do something with this information after it came, for example to put the sectors and objects on them in arrays, request doesnt work. I tried to put a timeout before the function to allow time to get info; i tried to put it on a button. Didn’t help. The code which blocks everything is in client.html between /* and */. It works great without this code.
-
server.js:var mysql = require('mysql'); var io = require('socket.io').listen(8080); var TESTGAME = 'testgame'; var TABLES_MAP1 = 'map1'; var client = mysql.createClient({ user: 'root', password: '', }); client.query('USE '+TESTGAME); client.query( ('SELECT * FROM '+TABLES_MAP1+' WHERE id_sector_x < 40 && id_sector_y < 40'), function(err, results, fields) { if (err) {throw err;} Map1 = (results); io.sockets.on('connection', function (socket) { socket.emit('info', Map1); socket.on('back', function (data) { console.log(data); }); }); client.end(); } ); -
client.html:<!doctype html> <html> <head> <meta charset="utf-8"> <title>Map</title> <script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script> <script src="json.js" type="text/javascript"></script> <script type='text/javascript'> window.onload = function() { var socket = io.connect('http://127.0.0.1:8080'); socket.on('info', function (data) { Mappp = (data); socket.emit('back', Mappp.length); }); }; Map1=Mappp; function mapp(){ m=0; //As info looks like this [1600] i need to make it look like this [40][40]. So this m will be m++ on each iteration to know what info should be put in. for (x=0;x<40;x++){ for (y=0;y<40;y++){ /* switch (Map1[m].type_sector) { case "grass": map[x][y]=0; [break] case "water": map[x][y]=1; [break] case "swamp": map[x][y]=2; [break] default: map[x][y]=0; [break] }; switch (Map1[m].obj_sector) { case "no": objectMap[x][y]=0; [break] case "wall": objectMap[x][y]=1; [break] default: objectMap[x][y]=0; [break] }; */ m++; } } window.alert('Done'); } setTimeout(mapp, 1000); </script> <form name=""> <input type="submit" value="call mapp" onclick=mapp()> </form> </head> <body> <script type="text/javascript"> </script> </body> </html>
Sorry for my English 🙂
You’re dealing with an asynchronous request. You won’t be able to set
Map1=Mappp;until after the request returns and your callback function is executed (sidenote: please, please usevarstatements). You sort of address this with your timeout, but because themapp()function depends onMap1being set synchronously, even if the request has returned andMapppis set,mapp()will still fail.To fix this, you need to make sure that anything that requires the data returned by your request isn’t executed until the request returns – that’s what the callback function is for. The easiest way to do this with your current code is probably to dispense with the
MapppandMap1variables entirely and pass the returned data tomapp()as a function argument, invoking the function in the callback:You’d need to adjust the
mapp()function for this to work: