title: Call a function after an asynchronous JavaScript function completes?
body: <p>I'm new to JavaScript, and I searched around for a solution to my problem. I'm really struggling to find the right answer. I think I might have to do something with callbacks, but I'm not sure.</p>
  
  <p>Basically, I am implementing a "like" button on my website. On clicking the "like" button, I need two main back-end things to happen: The database of "likes" should be updated, and an email notification should be sent to the person who got a "like". After clicking the "like" button, I render a "liked" button to show the user that it went through.</p>
  
  <p>Problem is, shooting the email takes a long time. So if I update the database and then send the email and <em>then</em> render the button, the user will be waiting a bit before he/she sees the button changed to a "liked" button. So instead, I would like to update the database, render the like button, and <em>then</em> shoot the email.</p>
  
  <p>In my JavaScript, I tried doing the following:</p>
  
  <pre><code>function foo()
  {
    xmlhttp1.onreadystatechange = liked( function() {
      xmlhttp2.open("POST", "async/async_likeEmail.php",true)
      xmlhttp2.setRequestHeader(...
      ...
      xmlhttp2.send(parameters);
    }
  
    xmlhttp1.open("POST", "async/async_likeUpdateDB.php", true)
    xmlhttp1.setRequestHeader(...
    ...
    xmlhttp1.send(parameters);
  }
  
  function liked(callback) {
    if (xmlhttp1.readyState == 4)
    {
      xmlhttp1.responseText;
      someElement.innerHTML = xmlhttp1.responseText; // render the "liked" button
      callback();
    }
  }
  </code></pre>
  
  <p>Doing it this way, the asynchronous "liked" function fails to get called. For some reason, passing in a callback breaks it. I've also tried not passing in a callback and instead, defining a separate "like_notify" function, and calling like_notify() inside of the asynchronous "liked" function also fails. </p>
  
  <p>Can someone let me know what I'm doing wrong and why these attempts have failed? Are callbacks not the solution to this problem?</p>