对于那个奇怪的线程标题很抱歉,但是我不知道该如何更好地描述我的问题。
我目前正在研究一个使用Microsoft Graph API的Java项目(这是我第一次使用Microsoft Graph API)。
我认为我的问题是Java的普遍问题。我有一个提供Graph API客户端的类,还有一个第二类,提供了我想用Graph API执行的所有操作。带有操作方法的类应将结果返回给客户端类。
一些代码。 我的客户类(我称之为操作的相关部分):
client = GraphServiceClientManager.getInstance().getGraphServiceClient();
Operations task = new Operations(client);
System.out.println(task.getUsernamebyUPN("USER UPN"));
我班上的操作:
public String username = "0";
public String getUsernamebyUPN(String UPN) {
client.users(UPN).buildRequest().get(new ICallback<User>() {
@Override
public void success(User user) {
username = user.displayName;
}
@Override
public void failure(ClientException ex) {
ex.printStackTrace();
}
});
return username;
}
所以问题是当我运行代码时,它将返回值为0的用户名,而不是我想要的用户名。返回后将更改用户名变量。
如果我在“用户名= user.displayName;”下添加System.out.prntln(用户名)成功方法中的一行我的输出将是:
0
The username I want
如何解决此问题?您需要更多代码吗?
非常感谢您的帮助。 :)
答案 0 :(得分:0)
该值将异步返回给回调函数,但是您可以强制程序在需要该值时等待返回。一种方法是返回一个值持有者类,该类将在您尝试获取该值之前阻塞,直到设置好该值为止,而回调函数会设置该值。
例如,以下类使用Phaser来控制此等待行为:
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Phaser;
public class FutureValue<T> {
private T value = null;
private Exception ex = null;
private Phaser phaser = new Phaser(1);
/**
* Get blocks until a value or an exception is set, after that it always
* returns immediately
*
* @return the value
* @throws ExecutionException
*/
public T get() throws ExecutionException {
phaser.register();
phaser.arriveAndAwaitAdvance();
if (ex != null) {
throw new ExecutionException(ex);
}
return value;
}
/**
* Sets the value and unblocks awaiting threads
*
* @param val
*/
public void set(T val) {
this.value = val;
phaser.forceTermination();
}
/**
* Sets an exception and unblocks awaiting threads
*/
public void setException(InterruptedException ex) {
this.ex = ex;
phaser.forceTermination();
}
}
您可以更改方法以返回FutureValue:
public FutureValue<String> getUsernamebyUPN(String UPN) {
final FutureValue<String> future = new FutureValue<String>();
client.users(UPN).buildRequest().get(new ICallback<User>() {
@Override
public void success(User user) {
future.set(user.displayName);
}
@Override
public void failure(ClientException ex) {
future.setException(ex);
}
});
return future;
}
另一种选择是更改逻辑,使其不获取值,而是观察事件,并通过回调发送事件。