So in my server code, variable invites is undefined outside of the success function.
function getInvites(id){
var InvitesTable = tables.getTable("Invites").where({"PlanID": id}).select("UserID","Attending");
var invites;
InvitesTable.read({ success: function(resultss) {
invites = resultss;
console.log(invites); //works here
}});
console.log(invites); //undefined here
}
From similar questions, I realize its because of it being asynchronous. So the success function call is run after the console.log(invites); //undefined here call.
My question is how do I stop that in Windows Azure?
Added code
function read(query, user, request) {
request.execute({
success: function(results) {
results.forEach(function(r) {
getInvites(r.id, function(invites) {
r.invites = invites;
});
});
request.respond();
}
});
}
function getInvites(id, cb){
var InvitesTable = tables.getTable("Invites").where({"PlanID": id}).select("UserID","Attending");
InvitesTable.read({ success: function(results) {
if (cb) cb(results);
}});
}
You don’t “stop that,” you design your application around the async nature of whatever environment you’re using.
I assume you’re trying to do something like this:
This obviously won’t work, since you return the value of
invitesbefore the async call completes.Instead, you write your app in async style:
This leaves out error handling code for the sake of simplicity, so you’d have to add that as well.
After seeing your full code, it looks like you have a simple problem of managing many parallel asynchronous operations. Consider what happens: your loop runs, iterating over an array of n objects. For each, you call
getInvites, which begins a database request and returns.This means your loop runs very quickly, but now you have n outstanding database requests that you must wait on before you can call
request.respond().An extremely basic solution would be to do something like count the number of times your
getInvitescallback is called, and then finally complete the request when that number reaches n.However, it is time-consuming and mistake-prone to manage this bookkeeping manually every time you make async requests. This is a situation where flow control libraries are extremely useful. I will use jQuery’s
Deferredin this example, since it may already be familiar to you (even if you don’t know you’ve actually used it before — if you’ve ever used jQuery’s XHR API, you’ve usedDeferreds).Given that you’re in a server environment, you obviously don’t have jQuery; however, there are people who have extracted only the code necessary for
Deferredfor you.Once we have
Deferreds for every pending request, we can usewhento register a callback that gets called only after all pendingDeferreds complete.Notes:
jQuery.when(or in this server-side case,Deferred.when) normally expects you to pass a fixed number ofDeferreds as arguments:However, we have a variable number of
Deferreds, so we mustapplyan array ofDeferreds towhenand then in thedonehandler, access each result via the implicitargumentsobject.Array.forEach(...)is slow. In most cases, it is better to use a regularforloop.