猿问

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

我正在使用纯 JS 开发一个项目,并且我正在尝试消除竞争条件。我刚刚遇到了 Promise 的概念,我正在为它们的工作原理而苦苦挣扎。


这是我正在尝试做的事情:用户可以将文件拖到拖放区,并在画廊中创建该文件的表示,并且它应该经历一个由进度条表示的过程:


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] = new newFile(id);.


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


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


我担心的是这个:


this.progress.endprog();

delete tracker[this.id];

这两件事都需要发生,但如果progress.endprog{}在文件(以及进度对象本身)被删除之前还没有完成,那么我担心会把事情搞砸。


我最初有一个set Timeout关于删除的问题,但这仍然感觉像是一种竞争条件,我正在寻找更优雅的东西并消除竞争条件。但我在挣扎。承诺可以帮助吗?还有其他我想念的方式吗?


编辑:添加更多细节


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


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()获取此引用之前被删除,它不会尝试访问不再存在的属性吗?


萧十郎
浏览 89回答 1
1回答

梦里花落0921

尝试这个: this.id = id; this.container = container; this.progress = progress; this.removeMe = function(id) {      this.progress.endprog();      delete tracker[id]; }回答您的评论,也许一个选项可以移动delete tracker[this.id];endprog 函数内部,因此您可以确保在此函数结束时调用,其他更复杂的选项可以是使用仅删除具有给定标志的跟踪器的进程.
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答