Вчера разбрах, че това, което правя, потенциално може да бъде проблем, ако не синхронизирам асинхронните си заявки - въпросът е дали наистина трябва.
Нека вземем следния сценарий: Имам изглед от най-високо ниво, който предава списък с данни List<SomeObject>
надолу към неговите подизгледи. Всички презентатори на подниво ще работят с този списък с данни чрез добавяне, премахване и модифициране на елементи от този списък.
Да приемем, че потребител прави нещо в потребителския интерфейс и след това натиска бутона „Запазване“ на множество екземпляри на изглед на подниво, което ще извика SubLevelPresenter.onSaveSomeObjectButtonClick()
. Това ще извърши RPC повикване, чийто резултат ще бъде добавен към списъка List<Somebject>
.
Моето предположение е, че е възможно, ако потребителят щракне върху два различни бутона за запазване, данните да пристигнат по едно и също време, задействайки onSaveSomeObjectButtonClick()
едновременно, което ще доведе до едновременен достъп до List<SomeObject>
.
Трябва ли да синхронизирам тези действия чрез прилагане на опашка, напр. или съм в безопасност поради някаква вътрешна магия на GWT/JavaScript, която не виждам тук?
public class TopLevelPresenter {
private List<SomeObject> someObjectList = new ArrayList<>();
private List<SubLevelPresenter> cache = new ArrayList<>();
public void TopLevelPresenter(TopLevelModel topLevelModel, TopLevelView topLevelView) {
this.topLevelModel = topLevelModel;
this.topLevelView = topLevelView;
for(int i = 0; i < topLevelModel.getNumOfSubViews(); i++) {
// Pass the data
SubLevelModel subLevelModel = new SubLevelModel(someObjectList);
SubLevelView subLevelView = new SubLevelView();
SubLevelPresenter subLevelPresenter = new SubLevelPresenter(subLevelModel, subLevelView);
cache.add(subLevelPresenter);
}
}
}
public class SubLevelModel() {
private List<SomeObject> someObjectList;
public SubLevelModel(List<SomeObject> someObjectList) {
this.someObjectList = someObjectList;
}
public void addSomeObject(SomeObject someObject) {
this.someObjectList.add(someObject);
}
public void removeSomeObject(SomeObject someObject) {
this.someObjectList.remove(someObject);
}
}
public class SubLevelPresenter() {
private SomeServiceAsync someService = /* .. */;
private SubLevelView subLevelView;
private SubLevelModel subLevelModel;
public SubLevelPresenter(SubLevelModel subLevelModel, SubLevelView subLevelView) {
this.subLevelView = subLevelView;
this.subLevelModel = subLevelModel;
}
public void onSaveSomeObjectButtonClick() {
SomeObject toSave = this.subLevelView.getSuggestionBox().getSelection();
someService.saveSomeObject(toSave, new AsyncCallback<SomeObject>() {
@Override
public void onFailure(Throwable caught) {
Window.alert("RPC to saveSomeObject() failed.");
}
@Override
public void onSuccess(SomeObject savedObject) {
SubLevelPresenter.this.subLevelModel.addSomeObject(savedObject);
}
});
}
}