我必须进行几次GWT-RPC调用。 我想像这样异步启动它们。
service.s1(param1, callback1);
service.s2(param2, callback2);
service.s3(param3, callback3);
我不确定如何“同步”三个回调。 下一步行动,例如call方法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个回调是“同时”调用这个scrviceclass
答案 0 :(得分:3)
这似乎是Promises可以解决的典型案例。
遵循DRY的原则,我将使用基于流行的jQuery Deferred实现为gwt编写的gwtquery Promises解决方案而不是编写自己的代码。
在您的情况下,您的代码可能如下所示:
// 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
答案 1 :(得分: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(); }
}
}
答案 2 :(得分:1)
他是关于Parallel asynchronous calls in 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);
}
答案 3 :(得分: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方法,这将检查请求&#39;数,例如:
private void dataFetched() {
if (counter.value() <= 0)
// proceed
}
IMO非常清晰优雅的做法。希望它有所帮助。