1

我必须进行几次 GWT-RPC 调用。我想像这样异步启动它们。

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

我不确定如何“同步”三个回调。下一个动作,例如调用方法nextMethod();应在三个回调完成后完成。是否有“最佳实践”如何做到这一点?

我想建立一个像这样的小服务类

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 个回调“同时”调用此服务类

4

4 回答 4

3

看来这是可以用Promises解决的典型案例。

遵循 DRY 的原则,我不会自己编写代码,而是使用gwtquery Promises解决方案,它是为 gwt 编写的,基于流行的 jQuery Deferred 实现。

在您的情况下,您的代码可能如下所示:

    // 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);  
} 

这是父回调的代码

于 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 回答