我在列表上有一个for循环:
boolean initialized = false
for(final Share share : shares) {
someInstance.check(new someCallback() {
@Override
public void onSuccess() {
// do something
}
});
}
initialized = true;
在每个步骤中执行异步操作,称为check()。我想在所有check()操作完成时设置initialized = true。 有没有办法在Java / GWT中做到这一点?
我如何知道For循环中的所有异步操作何时完成?
答案 0 :(得分:2)
每次调用onSuccess
时,只需增加一些共享计数器,该计数器计算已完成的数量。你知道你已经开始了多少(比如说N),所以一旦the finished counter
达到相同的值(N)你知道它们都已经完成了。然后完成的最后一个将设置initialized = true
。
答案 1 :(得分:2)
我不知道GWT是否有任何特殊限制,但你可以等到他们都成功,例如使用一个简单的CountDownLatch
final CountDownLatch latch = new CountDownLatch(shares.size());
for(final Share share : shares) {
someInstance.check(new someCallback() {
@Override
public void onSuccess() {
latch.countDown();
// do something
}
});
}
latch.await();
boolean initalized = true;
这将简单地阻止执行,直到每个回调计数一次为止。阻塞通常是一个坏主意。所以你可能也希望异步设置initialized
。一旦它成立,就使用一些回调。
答案 2 :(得分:0)
您可以使用此回调计数器实现。当所有回调都完成时,它会触发提供的AsyncCallback。类似于Promise.all()的东西。此实现具有锁定和解锁方法,以确保某些回调在必要时不会对其进行反制。
这是如何使用它:
CallbackCounter counter = new CallbackCounter(yourFinalCallback);
//counter.lock(); call this if methodWithCallback may execute callback synchronously
for (int i = 0; i < 10; i++)
{
AsyncCallback<Void> counterCallback = counter.async();
methodWithCallback(i, counterCallback);
}
//counter.unlock();
这是CallbackCounter类:
public class CallbackCounter
{
private int count;
private int maxCount;
private boolean failOnError;
private Throwable exceptionDuringLock;
private boolean unlocked;
private AsyncCallback<Void> callback;
public CallbackCounter(AsyncCallback<Void> callback)
{
this(true, callback);
}
public CallbackCounter(boolean failOnError, AsyncCallback<Void> callback)
{
this.failOnError = failOnError;
this.callback = callback;
count = 0;
maxCount = 0;
unlocked = true;
}
public int getCount()
{
return maxCount;
}
public LocalDatabaseRemoveCallback localDatabaseRemove()
{
maxCount++;
return new LocalDatabaseRemoveCallback()
{
@Override
public void onRemove(String key)
{
counterSuccess();
}
@Override
public void onError(String key, Throwable error)
{
counterFail(error);
}
};
}
public AsyncCallback<Void> async()
{
maxCount++;
return new AsyncCallback<Void>()
{
@Override
public void onSuccess(Void result)
{
counterSuccess();
}
@Override
public void onFailure(Throwable caught)
{
counterFail(caught);
}
};
}
public CommandCallback<Void> command()
{
maxCount++;
return new CommandCallback<Void>()
{
@Override
public void onCallback(Void data)
{
counterSuccess();
}
};
}
public SimpleCallback simple()
{
maxCount++;
return new SimpleCallback()
{
@Override
public void onCallback()
{
counterSuccess();
}
};
}
public void lock()
{
if (unlocked)
{
unlocked = false;
}
}
public void unlock()
{
if (!unlocked)
{
unlocked = true;
if (count >= maxCount)
{
if (exceptionDuringLock == null)
{
conterSuccessCallback();
}
else
{
Throwable e = exceptionDuringLock;
exceptionDuringLock = null;
conterFailCallback(e);
}
}
}
}
private void counterSuccess()
{
count++;
if (!unlocked)
{
return;
}
if (count >= maxCount)
{
conterSuccessCallback();
}
}
private void conterSuccessCallback()
{
if (callback != null)
{
AsyncCallback<Void> callbackToCall = callback;
callback = null;
callbackToCall.onSuccess(null);
}
}
private void counterFail(Throwable caught)
{
count++;
if (failOnError)
{
if (unlocked)
{
conterFailCallback(caught);
}
else
{
exceptionDuringLock = caught;
}
}
}
private void conterFailCallback(Throwable caught)
{
if (callback != null)
{
AsyncCallback<Void> callbackToCall = callback;
callback = null;
callbackToCall.onFailure(caught);
}
}
}