在提出问题之前,我最终想要解决的问题是查询 Firebase 数据库并根据结果编写代码的同步性。 一个简单的例子来说明:
Boolean userFound = false;
DatabaseReference userName = FirebaseDatabase.getInstance().getReference().child("Profiles").child("Name");
userName.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.getValue().toString();
userFound = true;
Toast.makeText(getBaseContext(), "Welcome back, " + name + ".", Toast.LENGTH_SHORT).show();
}
@Override
public void onCancelled(DatabaseError databaseError) {
//Never used this section
}
});
If (!userFound) {
Toast.makeText(getBaseContext(), "User not found.", Toast.LENGTH_SHORT).show();
}
在上面的示例中,侦听器在数据库中查找名称。 如果找到该名称,则会显示欢迎消息并将“userFound”设置为 true。 如果未找到名称,“userFound”将保持为 false,您可以生成一条未找到用户消息。
这样做的问题是,所有内容都在同一时刻运行,因此您总是会立即收到“找不到用户”消息,然后几秒钟后,侦听器可能会真正找到用户并说“欢迎回来”。
我一直在研究如何解决这个问题,并且我发现了 Java Promises。 我的方向正确吗? 以下是两个 Promise 示例:
CompletableFuture.supplyAsync(this::failingMsg)
.exceptionally(ex -> new Result(Status.FAILED))
.thenAccept(this::notify);
这段代码看起来很棒,这里的文章非常详细地介绍了它的用法:http://www.deadcoderising.com/java8-writing-asynchronous-code-with-completablefuture/
除此之外,它仅适用于 API 24 及更高版本。 这意味着您的应用程序无法在 90% 的设备上运行。 所以这基本上毫无价值。
另一种方法如下:
try {
Promise { client.newCall(request).execute() }
.then { ... }
.thenAsync { ... }
.then { ... }
} catch (e: Exception) {
...
}
如此处解释:https://medium.com/@sampsonjoliver/promises-in-android-and-java-d6b1c418ea6c
除了当我尝试使用这段代码时,没有 Promise 这样的东西。 它只是说它无法解析该符号。 所以这家伙写了一篇关于根本不存在的东西的文章。
我在这里看到的东西正确吗? 最终的结果是让我的应用程序等待任何数据库查找的结果,然后再继续处理代码。 如果我做不到这一点,那么数据库就完全没用了。
谢谢大家。 请帮忙!
使用异步 API 解决问题的方法几乎总是相同的:将需要访问数据的代码移至数据可用时调用的方法。
因此,在您的情况下,这意味着将支票和烤面包移至onDataChange
:
DatabaseReference userName = FirebaseDatabase.getInstance().getReference().child("Profiles").child("Name");
userName.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Boolean userFound = false;
String name = dataSnapshot.getValue().toString();
userFound = true;
Toast.makeText(getBaseContext(), "Welcome back, " + name + ".", Toast.LENGTH_SHORT).show();
if (!userFound) {
Toast.makeText(getBaseContext(), "User not found.", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
有关此内容的更多信息,请参阅:
https://pro4j.com/ 处查看。