等待异步回调完成并传递值
Wait for asynchronous callback to finish and pass the value
我有以下代码片段:
private ValContainer<CompletableFuture<String>> valContainer = new ValContainer<>();
public void fetchAsync(final String attrName) {
QueryAsyncCallback asyncCallback = new QueryAsyncCallback() {
@Override
public void onSuccess(Message response) {
final Data value = response.results().get("value");
String text = value.toString();
CompletableFuture<String> result = CompletableFuture.completedFuture(text);
valContainer.setVal(result);
}
@Override
public void onError(CallbackError error) {
LOG.info("Error occurred");
}
@Override
public void onTimeout() {
LOG.info("Timeout occurred");
}
};
Message request = new Messsage("com.example.val", "local", 0, "fetch");
request.parameters().put("name", attrName);
MsgOptions options = new MsgOptions(5000);
try {
queue.query(request, options, asyncCallback);
} catch (QueueAccessException e) {
e.printStackTrace();
}
}
现在,我可以很容易地得到我在 onSuccess()
回调中查询的值。 ValContainer
只是一个通用容器,因此我可以将值保存在匿名 class 中。不幸的是,在 Main 函数中我试图访问这个 valContainer
但不幸的是因为这是异步查询我得到 NullPointerException.
...
((JavaServiceImpl) javaService).fetchAsync("test");
System.out.println("inMain value: " + ((JavaServiceImpl) javaService).getValContainer().getVal().get()); <-- this is going to be NullPointerException
...
然后在 100 毫秒后,我在 onSuccess()
方法中获取值。这里基本上做 Thread.sleep(100)
就足以获取我希望获得的值,但我真的不想阻塞线程。有没有一种方法可以巧妙地做到这一点?
不要让 val
在 ValContainer
中未初始化。将其初始化为 new CompletableFuture<>()
。
private ValContainer<CompletableFuture<String>> valContainer = new ValContainer<>(new CompletableFuture<>());
public class ValContainer<T> {
T val;
public ValContainer(T val) {
this.val = val;
}
}
然后将您的 onSuccess
方法更改为
String text = value.toString();
valContainer.getVal().complete(text);
您不需要在 onSuccess
方法中创建 CompletableFuture
。
有了这个,[..]getValContainer().getVal().get()
阻塞直到未来完成。
我有以下代码片段:
private ValContainer<CompletableFuture<String>> valContainer = new ValContainer<>();
public void fetchAsync(final String attrName) {
QueryAsyncCallback asyncCallback = new QueryAsyncCallback() {
@Override
public void onSuccess(Message response) {
final Data value = response.results().get("value");
String text = value.toString();
CompletableFuture<String> result = CompletableFuture.completedFuture(text);
valContainer.setVal(result);
}
@Override
public void onError(CallbackError error) {
LOG.info("Error occurred");
}
@Override
public void onTimeout() {
LOG.info("Timeout occurred");
}
};
Message request = new Messsage("com.example.val", "local", 0, "fetch");
request.parameters().put("name", attrName);
MsgOptions options = new MsgOptions(5000);
try {
queue.query(request, options, asyncCallback);
} catch (QueueAccessException e) {
e.printStackTrace();
}
}
现在,我可以很容易地得到我在 onSuccess()
回调中查询的值。 ValContainer
只是一个通用容器,因此我可以将值保存在匿名 class 中。不幸的是,在 Main 函数中我试图访问这个 valContainer
但不幸的是因为这是异步查询我得到 NullPointerException.
...
((JavaServiceImpl) javaService).fetchAsync("test");
System.out.println("inMain value: " + ((JavaServiceImpl) javaService).getValContainer().getVal().get()); <-- this is going to be NullPointerException
...
然后在 100 毫秒后,我在 onSuccess()
方法中获取值。这里基本上做 Thread.sleep(100)
就足以获取我希望获得的值,但我真的不想阻塞线程。有没有一种方法可以巧妙地做到这一点?
不要让 val
在 ValContainer
中未初始化。将其初始化为 new CompletableFuture<>()
。
private ValContainer<CompletableFuture<String>> valContainer = new ValContainer<>(new CompletableFuture<>());
public class ValContainer<T> {
T val;
public ValContainer(T val) {
this.val = val;
}
}
然后将您的 onSuccess
方法更改为
String text = value.toString();
valContainer.getVal().complete(text);
您不需要在 onSuccess
方法中创建 CompletableFuture
。
有了这个,[..]getValContainer().getVal().get()
阻塞直到未来完成。