Попытка понять JS обещает устранить условие гонки - PullRequest
1 голос
/ 27 марта 2020

Я работаю над простым проектом JS, и у меня есть условие гонки, которое я пытаюсь устранить. Я только что столкнулся с концепцией обещаний, и я борюсь с тем, как они работают.

Вот что я пытаюсь сделать: пользователь может перетаскивать файлы в рабочую зону, и создается представление этого файла. в галерее, и он должен go через процесс, который представлен индикатором выполнения:

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;
}

Затем в другом месте программы, когда пользователь помещает файл в область удаления, мы добавляем a 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 Ответ

0 голосов
/ 27 марта 2020

Попробуйте это:

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

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

Отвечая на ваш комментарий, возможно, может быть вариант переместить delete tracker[this.id]; в функцию endprog, чтобы вы могли убедиться, что она вызывается в конце этой функции, а другие Более сложным вариантом может быть использование процесса, который удаляет только трекеры с заданным флагом.

...