4

在我的 GWT-Platform 应用程序中,我实现了一个方法,其中一个步骤是从服务器获取数据,下一步取决于它。我想阻止我的方法进一步执行代码,直到异步调用完成。

应该很简单,但我没有找到方法。

4

4 回答 4

6

我认为你错过了关于网络异步的观点。

在异步调用完成之前阻止客户端代码的执行被认为不是一种好的做法(它是一种反模式)。

因此,不要在异步代码完成之前阻止执行,请执行以下操作:

  1. 创建一个在异步代码完成时在全局 Eventbus 上触发的事件
  2. 在您的一位演示者中附加此事件的处理程序
  3. 启动异步代码
  4. 显示加载指示器
  5. 异步调用完成后,隐藏加载指示器并在 Eventbus 上触发 Event
  6. 在之前创建的 Handler 中处理下一步。
于 2012-06-19T12:36:06.027 回答
2

我不是 GWT 大师,但我知道如何以简单的方式做到这一点。如果有人告诉我如何以正确的方式进行操作,我将非常感激,因为我也对它感兴趣。您可以只创建包含所需代码的方法并将其调用 onSuccess 或执行以下操作:

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);
    }
}
于 2012-06-18T16:27:19.680 回答
1

为什么使用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) {
}
于 2012-06-19T10:31:40.150 回答
0

我不得不更改原始流程,基本上将其移动并链接到异步调用的 onSuccess()。

原来,流量是

  1. 用户单击弹出对话框的确定​​按钮
  2. validate(一切都是前端验证),如果验证错误,抛出异常并显示错误。诊断日志未关闭。
  3. 验证成功后,继续数据处理并关闭对话框。

现在在一个新的场景中,#2 验证被更改为需要一个异步回调到后端。所以#3 必须移动到链接到 validate 方法的回调。' 下面的代码片段

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);
}
于 2013-07-29T19:48:50.407 回答