What you need is a closure to preserve the value of roomid until the asynchronous call is finished. One way to create a closure is using an immediate function where you pass the value of roomid into it as a parameter.
There are a billion articles that explain closures in detail but simply put: a closure is any function that accesses a variable from an outer scope. A special object call a closure is created in this situation in order to preserve the memory locations of all the objects/variables that are referenced within the inner function, creating a context of sorts.
In my example, once you make this closure, you are effectively hiding roomid in the outer scope because you have an immediate function with a variable of the exact same name. So therefore, you will only be accessing the value within the immediate function and it will have the correct id when the ajax call completes.
$(".room").each(function () {
i = i + 1;
alert(i);
roomid = $(this).attr("id");
alert(roomid);
(function(roomid) {
$.get("QueryRoom.aspx?ID=" + roomid, function (data) {
$("#" + roomid).html(data);
});
})(roomid);
});
});