Java 如何知道For循环中的所有异步操作何时完成?
我在列表上有一个for循环:Java 如何知道For循环中的所有异步操作何时完成?,java,gwt,Java,Gwt,我在列表上有一个for循环: boolean initialized = false for(final Share share : shares) { someInstance.check(new someCallback() { @Override public void onSuccess() { // do something } }); } initialized = true;
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循环中的所有异步操作何时完成?每次调用
onSuccess
时,只需增加一些共享计数器,计算完成的数量。你知道你已经开始了多少次(比如N),所以一旦完成的计数器达到相同的值(N),你就知道它们都完成了。然后最后一个完成的将设置initialized=true
我不知道GWT是否有任何特殊的限制,但是您可以等到它们都成功了,例如使用一个简单的倒计时闩锁
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;
这将简单地阻止执行,直到每个回调都倒计时一次。但阻塞通常是个坏主意。因此,您可能还需要同步设置初始化。并在其为真时使用一些回调。您可以使用此回调计数器实现。当所有回调完成时,它将激发提供的异步回调。类似于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=newcallbackcounter(yourlfinalcallback);
//counter.lock();如果methodWithCallback可以同步执行回调,则调用此函数
对于(int i=0;i<10;i++)
{
AsyncCallback counterCallback=counter.async();
methodWithCallback(i,反向回调);
}
//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);
}
}
}
公共类回调计数器
{
私人整数计数;
私有整数最大计数;
私有布尔故障诊断错误;
私用一次性锁;
私有布尔解锁;
私有异步回调;
公共回调计数器(异步回调)
{
这(对,回调);
}
公共回调计数器(布尔failOnError、异步回调)
{
this.failOnError=failOnError;
this.callback=回调;
计数=0;
最大计数=0;
解锁=真;
}
public int getCount()
{
返回最大计数;
}
公共LocalDatabaseRemoveCallback localDatabaseRemove()
{
maxCount++;
返回新的LocalDatabaseRemoveCallback()
{
@凌驾
移除时的公共void(字符串键)
{
反成功();
}
@凌驾
public void onError(字符串键,可丢弃错误)
{
反邮件(错误);
}
};
}
公共异步回调异步()
{
maxCount++;
返回新的AsyncCallback()
{
@凌驾
成功时公开作废(作废结果)
{
反成功();
}
@凌驾
失败时的公共无效(可丢弃)
{
反帆(被抓住);
}
};
}
公共命令回调命令()
{
maxCount++;
返回新的CommandCallback()
{
@凌驾
公共void onCallback(void数据)
{
反成功();
}
};
}
public SimpleCallback simple()
{
maxCount++;
返回新的SimpleCallback()
{
@凌驾
public void onCallback()
{
反成功();
}
};
}
公共无效锁()
{
如果(未锁定)
{
解锁=假;
}
}
公开作废解锁()
{
如果(!解锁)
{
解锁=真;
如果(计数>=最大计数)
{
如果(例外DuringLock==null)
{
contertSuccessCallback();
}
其他的
{
可丢弃的e=例外的DuringLock;
exceptionDuringLock=null;
contertfail(e);
}
}
}
}
私有无效反成功()
{
计数++;
如果(!解锁)
{
返回;
}
如果(计数>=最大计数)
{
contertSuccessCallback();
}
}
私有void contersuccescallback()
{
if(回调!=null)
{
AsyncCallback callbackToCall=回调;
callback=null;
callbackToCall.onSuccess(空);
}
}
私人空位反帆(可丢弃)
{
计数++;
如果(失败者错误)
{
如果(未锁定)
{
contertfailcallback(捕获);
}
其他的
{
exceptionDuringLock=捕获;
}
}
}
私有void conterFailCallback(可丢弃捕获)
{
if(回调!=null)
{
AsyncCallback callbackToCall=回调;
callback=null;
callbackToCall.onFailure(捕获);
}
}
}
someCallback是接口还是类?如果是一个类,您可以添加一个静态布尔方法processedAll()
或其他东西,以及一个静态someCallback[]
。该方法在数组中循环,检查以确保每个数组都已完成。实际上有几种方法可以做到这一点。如果知道someCallback
是一个类还是一个接口,或者倒计时到0,那就很好了,这样除了初始化计数器的位置之外,什么都不需要知道一个幻数。@zapl是的,那就更好了。