I'm finding myself writing a lot of spaghetti in Javascript when I have to deal with asynchronous applications (specially when dealing with OpenSocial code where all the data has to be obtained through JS). The usual pattern is something like:
- User logs into the application for the first time, get his data.
- Do A on his data (e.g. get his friends by sending a request to the server).
- Do B on this data (e.g. send his friends to the server for some processing).
- Do C on his data (e.g. check that the server response is valid so we can do something else).
Note that this sequential execution path (1 => 2 => 3 => 4) doesn't fit well the async. nature of Ajax so the user ends up waiting for a long time and the code turns into a mess since every step depends on the previous ones.
An example with code:
gadgets.util.registerOnLoadHandler(setupUser())
...
function setupUser() {
var req = [get data and setup request]
req.send(some_url, some_data, function(response) { getFriendsFor(response.user) });
}
function getFriendsFor(user) {
var friends = [get friends from user]
var req = [setup request]
req.send(some_other_url, some_other_data, function(response { validateFriendsResponse(response.friends) });
}
function validateFriendsResponse(friends) {
if (friends.valid())
...
loadCanvas();
}
You can see that each function depends on the previous one, and what's worse, it has to be called in a specific order to be useful. It gets worse when you have to add stuff like showing/hiding loading screens and other gimmicks while the user waits.
How would you go about fixing this?