title: Trying to understand JS promises to eliminate a race condition
body: <p>I'm working on a project in plain JS, and I've got a race condition that I'm trying to eliminate. I just encountered the concept of promises and I'm struggling with how they work.</p>
  
  <p>Here's what I'm trying to do: the user can drag files to a drop zone, and a representation of that file gets created in a gallery, and it's supposed to go through a process that is represented by a progress bar:</p>
  
  <pre><code>var tracker = {}; // this will have dropped-file objects added
  var gallery = document.getElementById('gallery');
  
  function newFile(id) {
       (declaration of various properties)
       var container = document.createElement('DIV');
  
       (then the creation of various elements within the container)
  
       var progress = new progbar(id);  // goes to a constructor to create the progress bar
       container.appendChild(progress);
       gallery.appendChild(container);
  
       this.id = id;
       this.container = container;
       this.progress = progress;
  
       this.removeMe = function() {
            this.progress.endprog();
            delete tracker[this.id];
       }
  
       return this;
  }
  </code></pre>
  
  <p>Then elsewhere in the program, when the user drops a file into the drop area, we add a <code>tracker[id] = new newFile(id);</code>.</p>
  
  <p>The problem comes if the user clicks the progress bar's "cancel" link: the file object's <code>removeMe()</code> method is invoked, it calls the end of the progress bar with <code>this.progress.endprog()</code>, and then deletes itself from the the tracker object.</p>
  
  <p>If the user drops the same file, then I check <code>tracker</code> and if the file exists the process ends with an alert to the user. But if they've started the processing of that file and cancelled it, I want them to be able to drop the file again. So though I do leave behind the div of the cancelled file (so marked), the file's object is gone from <code>tracker</code> and so it can be dropped again.</p>
  
  <p>What I'm concerned about is this:</p>
  
  <pre><code>this.progress.endprog();
  delete tracker[this.id];
  </code></pre>
  
  <p>Both of those things need to happen, but if <code>progress.endprog{}</code> has not finished before the file (and thus the progress object itself) is deleted, then I'm worried about screwing things up.</p>
  
  <p>I originally had a <code>set Timeout</code> on the deletion, but that still felt like a race condition, and I was looking for something more elegant and eliminate the race condition. But I'm floundering. Can a promise help? Is there some other way I'm missing?</p>
  
  <p>EDIT: ADDING MORE DETAIL</p>
  
  <p>A piece of information is important here that I forgot to include: the progress bar object makes various self-references:</p>
  
  <pre><code>function progbar(id) {
       (declaration of various properties)
       var bar = document.createElement('DIV');
       [file container].appendChild(bar);
       this.bar = bar;
       this.width = 0;
       this.fillup;
  
       this.startprog = function () {
            this.fillup = setInterval( [process to check for correct length] );
       }
  
       this.endprog = function () {
            [other stuff, and then...]
            clearInterval(this.fillup);
            [then more stuff]
       }
  
       return this;
   }
  </code></pre>
  
  <p>So you can see that there is at least a reference to the <code>setInterval</code> which is stored as a property of the object. If the file object is deleted before <code>endprog()</code> gets to this reference, will it not be trying to access a property that no longer exists?</p>