为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

萧十郎 2022-06-05 16:30:24
我正在使用纯 JS 开发一个项目,并且我正在尝试消除竞争条件。我刚刚遇到了 Promise 的概念,我正在为它们的工作原理而苦苦挣扎。这是我正在尝试做的事情:用户可以将文件拖到拖放区,并在画廊中创建该文件的表示,并且它应该经历一个由进度条表示的过程:var tracker = {}; // this will have dropped-file objects addedvar 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()获取此引用之前被删除,它不会尝试访问不再存在的属性吗?
查看完整描述

1 回答

?
梦里花落0921

TA贡献1772条经验 获得超6个赞

尝试这个:


 this.id = id;

 this.container = container;

 this.progress = progress;


 this.removeMe = function(id) {

      this.progress.endprog();

      delete tracker[id];

 }

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


查看完整回答
反对 回复 2022-06-05
  • 1 回答
  • 0 关注
  • 88 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信