title: Asynchronous JS issue -- Variable scoping or other mistake?
body: <p>I have a listener on a <code>select</code> element's <code>change</code> event: on change, a file is fetched and a complicated SVG is calculated and loaded to the DOM (read: a fair number of CPU cycles required). Issue is if you change the <code>select</code> very quickly (via coded keyboard shortcuts), multiple things are loaded to the SVG container -- I only want one loaded at a time. To try to remedy this, I've done this (semi-pseudo):</p>
  
  <pre><code>select.on("change", function() { queue(this.val); });
  
  var queuedFile, state = "ready";
  function queue(file) {
      queuedFile = file;
      // NB: in real code, queuedFile is a property and the getter empties the queue
      if (state === "ready") { loadFile(queuedFile); }
  }
  
  function loadFile(file) {
      state = "busy";
  
      ajaxGet(file, function(result) {
  
          // lots of statements, iterators, calls to other fns
  
          state = "ready";
          // NB: again in real code the getter empties the queue
          var qf = queuedFile;
          if (qf) { clearSVG(); loadFile(qf); }
  
      }); // end ajaxGet
  }
  </code></pre>
  
  <p>That is to say: on <code>select</code> change, queue the new file and if the file loader is not busy loading another file, load it, else do nothing. When the file loader is done, if there's a queued file, clear the SVG and load the queued file. Seems like this should only allow one file in the SVG container at once.</p>
  
  <p>In practice, <code>state</code> is never <code>"busy"</code> when it's checked in <code>queue()</code>, so I'm still getting multiple files loaded to the SVG. A <code>console.log(state)</code> right after <code>state = "busy"</code> shows <code>"busy"</code> though. What am I missing here? I don't think it's an issue with the scope of <code>queuedFile</code>.</p>
  
  <hr>
  
  <p>For completeness, my queue property is this:</p>
  
  <pre><code>// given: all of this code is enclosed in a function that returns an object "viewer".
  // (only one instance of the "viewer" is created)
  
  Object.defineProperty(viewer, "queuedFile", {
      get: function () {
          console.log("dequeuing", this.filequeue);
          var buffer = this.filequeue;
          this.filequeue = null;
          return buffer;
      },
      set: function (newval) {
          console.log("queuing", newval);
          this.filequeue = newval;
      }
  });
  </code></pre>