Question:

In the following program, dbGetUser and registerUser are non-blocking (asynchronous) function calls. The idea is to first query some database for a user and then call registerUser with the resulting object. registerUser performs various asynchronous operations and takes a callback (continuation) as argument. On completion, registerUser passes a response object to the callback with a boolean property success to indicate the result of registering the user. Finally, the program should take some action based on whether the user was registered or not.

function callback(user) {
  registerUser(user, function(response) {
    user.registered = response.success;
  });

  if (user.registered) {
    sendPandaBearTo(user);
  } else {
    doSomethingElse();
  }
}

/* Program starts here */
dbGetUser('Bob', callback);

But there is a major flaw in this piece of code. What is it?

Toggle answer

Answer:

Since registerUser returns immediately, checking the registered property on the user object presents a race condition in the above code (the callback may or may not have been invoked at the time the if-statement is executed). Moving the relevant portion of the code to inside the callback solves the problem:

registerUser(user, function(response) {
  user.registered = response.success;
  if (user.registered) {
    sendPandaBearTo(user);
  } else {
    doSomethingElse();
  }
});