4

私のGWT-Platformアプリケーションでは、1つのステップがサーバーからデータをフェッチし、次のステップがそれに依存するメソッドを実装しました。Async呼び出しが完了するまで、コードがそれ以上実行されないようにしたい。

単純なものでなければなりませんが、私は方法を見つけていません。

4

4 に答える 4

6

Webが非同期であるという点を見逃していると思います。

非同期呼び出しが終了するまでクライアント側のコードの実行をブロックすることは、良い習慣とは見なされません(むしろアンチパターンです)。

したがって、非同期コードが終了するまで実行をブロックする代わりに、次のようにします。

  1. 非同期コードが終了したときにグローバルイベントバスで発生するイベントを作成します
  2. プレゼンターの1人にこのイベントのハンドラーをアタッチします
  3. 非同期コードを開始します
  4. ローディングインジケーターを表示する
  5. 非同期呼び出しが終了したら、読み込みインジケーターを非表示にして、イベントバスでイベントを発生させます
  6. 前に作成したハンドラーで次のステップを処理します。
于 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. ユーザーがpoopupダイアログの[OK]ボタンをクリックします
  2. 検証(すべてがフロントエンド検証です)、検証エラーの場合は、例外をスローしてエラーを表示します。diaglogは閉じられていません。
  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 に答える