在我提出问题之前,我最终要解决的问题是查询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。我正朝着正确的方向前进吗?这是两个承诺的例子:
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这样的东西。它只是说它无法解析符号。所以这个人写了一篇关于甚至根本不存在的文章。
我在这看正确的东西吗?最终的游戏是让我的应用程序在继续处理代码之前等待任何数据库查找的结果。如果我不能这样做,那么数据库就变得完全没用了。
谢谢你们。请帮忙!
答案 0 :(得分:1)
使用异步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();
}
});
有关详情,请参阅: