1

いくつかの GWT-RPC 呼び出しを行う必要があります。このように非同期で起動したいと思います。

service.s1(param1, callback1);
service.s2(param2, callback2);
service.s3(param3, callback3);

3 つのコールバックを「同期」する方法がわかりません。次のアクション。たとえば、メソッド nextMethod() を呼び出します。3 つのコールバックが完了した後に実行されます。これを行うための「ベストプラクティス」はありますか?

このような小さなサービスクラスを構築することを考えました

public class ServiceSync
{ private boolean[] callReady;

  public ServiceSync(int n)
  { callReady = new boolean[n];
    for(int i=0; i<n;i++)
    {  callReady[i]=false;
    }
  }

  public boolean setReady(int i)
  { callReady[i]=true;
    for(boolean b : callReady)
    { if (!b) return false;    
    }
    return true;
  }
}

コールバックで私は言うだろう

if (serviceSync.setReady(myId))
{ nextMethod();}

しかし、それが良いアイデアかどうかはわかりません。特に、2 つのコールバックがこの scrviceclass を「同時に」呼び出している場合、問題が発生しないかどうかはわかりません。

4

4 に答える 4

3

これはPromisesで解決できる典型的なケースのようです。

DRYの原則に従って、独自のコードを作成する代わりに、人気のあるjQueryDeferred実装に基づいてgwt用に作成されたgwtqueryPromisesソリューションを使用します。

あなたの場合、あなたのコードは次のようになります:

    // Create 3 promises to be used in RPC
    PromiseRPC<String> promise1 = new PromiseRPC<String>();
    PromiseRPC<String> promise2 = new PromiseRPC<String>();
    PromiseRPC<String> promise3 = new PromiseRPC<String>();

    // Fire the asynchronous requests
    greetingService.greetServer(textToServer1, promise1);
    greetingService.greetServer(textToServer2, promise2);
    greetingService.greetServer(textToServer3, promise3);

    GQuery
          // 'when' returns a new promise which monitors all of its subordinates
          .when(promise1, promise2, promise3)
          // 'done' will be executed only in the case all promises succeed
          .done(new Function() {
            public void f() {
              // each promise store its result in a fixed position of the argument list
              String textFromServer1 = arguments(0, 0);
              String textFromServer2 = arguments(1, 0);
              String textFromServer3 = arguments(2, 0);
            }
          });

    // If you want you could fire requests here instead than above
于 2013-03-22T23:05:17.953 に答える
2

次のように、コールバックの状態でレシーバーを宣言します。

public class CallResultReceiver {

   boolean call1Done, call2Done, call3Done;

   public void onCall1Success() { 
      call1Done = true;
      if (call1Done && call2Done && call3Done) { doGreatThings(); }
   }

   public void onCall2Success() { 
      call2Done = true;
      if (call1Done && call2Done && call3Done) { doGreatThings(); }
   }

   public void onCall3Success() { 
      call3Done = true;
      if (call1Done && call2Done && call3Done) { doGreatThings(); }
   }
}
于 2013-03-22T19:57:36.297 に答える
1

彼は、 GWT での並列非同期呼び出しに関する最高の記事です。

単純な ParentCallBack を作成することで、作業を簡単かつ効率的にすることができます。

public void someGwtClientSideMethod() {   
  SomeServiceAsync someService = GWT.create(SomeService.class);  
  ParallelCallback fooCallback = new ParallelCallback();  
  ParallelCallback barCallback = new ParallelCallback();  
  ParentCallback parent = new ParentCallback(fooCallback, barCallback) {   
    public void handleSuccess() {  
      doSomething(getCallbackData(0), getCallbackData(1));  
    }  
  };  
  someService.foo(fooCallback);  
  someService.bar(barCallback);  
} 

Parent Callbackのコードは次のとおりです。

于 2013-03-23T07:28:26.850 に答える
0

提示された問題に対する私のアプローチは次のとおりです。

まず、並列非同期の問題で使用するために、ある種の SynchronizedCounter が必要です。

public class SynchronizedCounter {

    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

次のステップは、RPC メソッドを呼び出すことです。

private void fetchData() {
    getFirst();
    getSecond();
    getThird();
    getFourth();
}

すべての RPC メソッドは、リクエストの前にカウンターをインクリメントし、呼び出しが成功した直後にカウンターをデクリメントする必要があります。すべての RPC メソッドは、RPC 呼び出しの後に final メソッドを呼び出します。これにより、リクエストの数がチェックされます。例:

private void dataFetched() {
    if (counter.value() <= 0)
        // proceed
}

IMOは非常に明確でエレガントなアプローチです。それが役に立てば幸い。

于 2016-09-26T13:29:29.487 に答える