Javascript 试图理解JS承诺消除竞争条件

Javascript 试图理解JS承诺消除竞争条件,javascript,promise,race-condition,Javascript,Promise,Race Condition,我在用纯JS做一个项目,我有一个种族条件,我正试图消除它。我刚刚遇到了承诺的概念,我正在努力研究它们是如何工作的 我想做的是:用户可以将文件拖到拖放区,然后在图库中创建该文件的表示,该文件应该经过一个由进度条表示的过程: var tracker = {}; // this will have dropped-file objects added var gallery = document.getElementById('gallery'); function newFile(id) {

我在用纯JS做一个项目,我有一个种族条件,我正试图消除它。我刚刚遇到了承诺的概念,我正在努力研究它们是如何工作的

我想做的是:用户可以将文件拖到拖放区,然后在图库中创建该文件的表示,该文件应该经过一个由进度条表示的过程:

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;
}
然后在程序的其他地方,当用户将文件放入放置区域时,我们添加一个
tracker[id]=newFile(id)

如果用户单击进度条的“取消”链接,就会出现问题:调用文件对象的
removeMe()
方法,它使用
this.progress.endprog()
调用进度条的末尾,然后从跟踪器对象中删除自身

如果用户删除了同一个文件,那么我将检查
tracker
,如果该文件存在,则进程将以向用户发出警报结束。但是,如果他们已经开始处理该文件并取消了它,我希望他们能够再次删除该文件。因此,尽管我确实留下了已取消文件的div(如此标记),但该文件的对象已从
tracker
中消失,因此可以再次删除它

我关心的是:

this.progress.endprog();
delete tracker[this.id];
这两种情况都需要发生,但是如果
progress.endprog{}
在文件(以及progress对象本身)被删除之前还没有完成,那么我担心会把事情搞砸

我最初在删除时设置了一个
超时时间
,但这仍然感觉像是一个竞争条件,我正在寻找更优雅的东西并消除竞争条件。但我在挣扎。承诺能帮上忙吗?还有什么我错过的方法吗

编辑:添加更多详细信息

这里有一条信息很重要,我忘了包括:进度条对象进行各种自引用:

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;
 }
因此,您可以看到至少有一个对
setInterval
的引用,它存储为对象的属性。如果文件对象在
endprog()
访问此引用之前被删除,它是否会尝试访问不再存在的属性?

尝试以下操作:

 this.id = id;
 this.container = container;
 this.progress = progress;

 this.removeMe = function(id) {
      this.progress.endprog();
      delete tracker[id];
 }
回答您的评论,也许可以选择移动
删除跟踪器[this.id]在endprog函数中,因此您可以确保在该函数结束时调用,其他更复杂的选项可以是使用仅删除具有给定标志的跟踪器的进程。

尝试以下操作:

 this.id = id;
 this.container = container;
 this.progress = progress;

 this.removeMe = function(id) {
      this.progress.endprog();
      delete tracker[id];
 }

回答您的评论,也许可以选择移动
删除跟踪器[this.id]在endprog函数内,因此您可以确保在该函数结束时调用,其他更复杂的选项可以是使用仅删除具有给定标志的跟踪器的进程。

我应该添加更多细节,该死。endprog()函数对自己的属性进行各种引用。我关心的是,如果在EntPro()结束之前删除了跟踪器[ID],那么在EntPrPro()的中间,文件对象(因此进度条对象?)被删除。因此,在终结进程的中间,它的父对象可能不再存在。这有意义吗?我将编辑原件以反映这一点。@user3281644检查新答案这是一个想法。我认为,一旦调用了函数,就会调用整个函数。但是如果它是一个对象中的一个方法,我不知道。我认为解决方案最终将是一个fileTracker对象和一个progressTracker对象,因此它们可以彼此独立运行,但具有相似的ID。这让人感觉不那么优雅,也不太依赖协调的ID。我会试试你的建议,把删除放在最后一个函数调用的末尾,看看是否有效。谢谢Andreu:把delete命令放在endprog()中确实有效。然而,我正在考虑是否明智的做法是让这样一个对象删除自己,而它除了自删除之外还有其他方法。但它确实奏效了!我应该多加一些细节,该死的。endprog()函数对自己的属性进行各种引用。我关心的是,如果在EntPro()结束之前删除了跟踪器[ID],那么在EntPrPro()的中间,文件对象(因此进度条对象?)被删除。因此,在终结进程的中间,它的父对象可能不再存在。这有意义吗?我将编辑原件以反映这一点。@user3281644检查新答案这是一个想法。我认为,一旦调用了函数,就会调用整个函数。但是如果它是一个对象中的一个方法,我不知道。我认为解决方案最终将是一个fileTracker对象和一个progressTracker对象,因此它们可以彼此独立运行,但具有相似的ID。这让人感觉不那么优雅,也不太依赖协调的ID。我会试试你的建议,把删除放在最后一个函数调用的末尾,看看是否有效。谢谢Andreu:把delete命令放在endprog()中确实有效。然而,我正在考虑是否明智的做法是让这样一个对象删除自己,而它除了自删除之外还有其他方法。但它确实奏效了!