爪哇语中的应许



在我提出问题之前,我最终试图解决的问题是查询我的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"将保持为假,您可以生成"找不到用户"消息。

这样做的问题是一切都在同一时刻运行,因此您将始终立即收到"找不到用户"消息,然后几秒钟后,侦听器可能会真正找到用户并说"欢迎回来"。

我一直在研究如何解决这个问题,我找到了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

除了当我尝试使用此代码时,没有承诺这样的东西。 它只是说它无法解析符号。 所以这个家伙写了一篇关于甚至不存在的东西的文章。

我在这里看对的东西吗? 最终的结果是让我的应用在继续处理代码之前等待任何数据库查找的结果。 如果我不能做到这一点,那么数据库将变得完全无用。

谢谢大家。 请帮忙!

使用异步 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();
}
});

有关此内容的更多信息,请参阅:

  • 在 Firebase 侦听器中设置单例属性值
  • 道格的优秀博客文章
  • 从火库查询数据
  • 等待 Firebase 异步检索数据在安卓
  • 处理异步任务返回的数据 (Firebase)

最新更新