Javascript 试图理解JS承诺消除竞争条件
我在用纯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) {
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()中确实有效。然而,我正在考虑是否明智的做法是让这样一个对象删除自己,而它除了自删除之外还有其他方法。但它确实奏效了!