Вчера я понял, что то, что я делаю, потенциально может быть проблемой, если я не синхронизирую свои асинхронные запросы - вопрос в том, действительно ли это нужно.
Давайте возьмем следующий сценарий: у меня есть представление верхнего уровня, которое передает список данных 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);
}
});
}
}