Запретить вызов метода, пока асинхронный вызов не завершит GWT-платформу

В моем приложении GWT-платформы я реализовал метод, в котором одним шагом является получение данных с сервера, а следующий шаг зависит от него. Я хочу запретить мой метод для дальнейшего выполнения кода до завершения асинхронного вызова.

Должно быть что-то простое, но я не нахожу способа.


person Bhavesh    schedule 18.06.2012    source источник


Ответы (4)


Я думаю, вы упускаете из виду, что сеть асинхронна.

Не считается хорошей практикой (это скорее антишаблон) блокировать выполнение вашего клиентского кода до завершения асинхронного вызова.

Поэтому вместо того, чтобы блокировать выполнение до тех пор, пока ваш асинхронный код не будет завершен, выполните следующие действия:

  1. Создайте событие, которое запускается на глобальной шине событий, когда ваш асинхронный код завершен.
  2. Прикрепите обработчик для этого события в одном из ваших докладчиков.
  3. Запустите асинхронный код
  4. Показать индикатор загрузки
  5. Когда асинхронный вызов завершен, скройте индикатор загрузки и запустите событие на шине событий.
  6. Обработайте следующий шаг в обработчике, который вы создали ранее.
person Ümit    schedule 19.06.2012

Я не гуру GWT, но я знаю, как это сделать простым способом. Буду очень признателен, если кто-нибудь подскажет, как это сделать правильно, так как меня это тоже интересовало. Вы можете просто создать метод, который будет содержать требуемый код и вызывать его при успехе, или сделать что-то вроде этого:

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;

public class Aaa implements EntryPoint {

    private final MyServiceAsync service = GWT
            .create(MyService.class);
    private Timer t;

    public void onModuleLoad() {
        t = new Timer() {
            @Override
            public void run() {
                // Make something or call function
                Window.alert("Next Step");
            }
        };
        final Button sendButton = new Button("Send");
        sendButton.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                service.sendInfo("Send First Step Info",
                        new AsyncCallback<String>() {
                            @Override
                            public void onSuccess(String result) {
                                Window.alert("Success Call");
                                // Call Next step code or function
                                t.schedule(1);

                            }

                            @Override
                            public void onFailure(Throwable caught) {
                                Window.alert("Failure Call");
                            }
                        });
            }
        });
        RootPanel.get().add(sendButton);
    }
}
person Taras Lazarenko    schedule 18.06.2012
comment
Привет, Тарас. Пожалуйста, рассмотрите следующий фрагмент кода и дайте мне знать, как он будет работать, как вы предлагаете, public void someMethod(){ step1; шаг 2; // А вот и асинхронный вызов step3; // Я хочу выполнить этот шаг только после завершения шага 2. Что мне сказать GWT, чтобы он дождался завершения асинхронного вызова? } Я знаю, что мы идем против асинхронного поведения, но в моем случае это необходимо. - person Bhavesh; 19.06.2012

Зачем использовать Timer?

final Button sendButton = new Button("Send");
sendButton.addClickHandler(new ClickHandler() {

    @Override
    public void onClick(ClickEvent event) {
        service.sendInfo("Send First Step Info",
                new AsyncCallback<String>() {
                    @Override
                    public void onSuccess(String result) {
                        Window.alert("Success Call");
                          nextStep(result);
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        Window.alert("Failure Call");
                    }
                });
    }
});

private void nextStep(String data) {
}
person Sydney    schedule 19.06.2012

Мне пришлось изменить исходный поток, в основном переместить его и связать с асинхронным вызовом onSuccess().

Первоначально поток был

  1. пользователь нажимает кнопку Ok в диалоговом окне poopup
  2. проверить (все это проверка переднего плана), если при проверке ошибка, выдать исключение и показать ошибку. диалог не закрывается.
  3. После успешной проверки продолжите обработку данных и закройте диалоговое окно.

Теперь в новом сценарии проверка № 2 изменена, чтобы требовать асинхронного обратного вызова к серверной части. Поэтому № 3 нужно переместить в цепочку обратного вызова метода проверки. ' Фрагменты кода ниже

public void onValidationDataReady(List<Long> existingTests) throws ValidationException {

    if (!existingTests.isEmpty()) {
        throw new ValidationException("The entered name has already been used.");
    }

    //only after  the validation do we proceed with the original OK click 
    proceedOkClick(testNameField.getValue());
}

public void proceedOkClick(String data) {
    // proceed only after the async call

    if (callback != null) {
        callback.onDialogResult(true, data);
    }

    clearDialog();
}


public boolean validateInputs() throws ValidationException {
    //async call to get data from back end.
            //pass in a Callback 
    testNameValidator.validate(testNameField.getValue(), new DataReadyCallback<List<Long>>() {
        @Override
        public void onDataReady(List<Long> existingTests) {
            onValidationDataReady(existingTests);
        }
    });
    return true;
}

//The call back interface. 
public interface DataReadyCallback<T> {
void onDataReady(T data);
}
person Tony    schedule 29.07.2013