Java 中的 Promise

问题描述 投票:0回答:2

在提出问题之前,我最终想要解决的问题是查询 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 这样的东西。 它只是说它无法解析该符号。 所以这家伙写了一篇关于根本不存在的东西的文章。

我在这里看到的东西正确吗? 最终的结果是让我的应用程序等待任何数据库查找的结果,然后再继续处理代码。 如果我做不到这一点,那么数据库就完全没用了。

谢谢大家。 请帮忙!

java android firebase firebase-realtime-database
2个回答
2
投票

使用异步 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 Listener 中设置 Singleton 属性值
  • Doug 的精彩博客文章
  • 从firebase查询数据
  • 等待Firebase异步在android中检索数据
  • 处理异步任务返回的数据 (Firebase)

0
投票
我为 java 和 kotlin 编写了一个 Promise 库。它更易于使用且轻巧,请在

https://pro4j.com/ 处查看。

  • 快速启动
  • 代码和示例
  • Android 示例
  • Java 示例
  • Kotlin 示例
  • Java 扩展
  • Kotlin 扩展
© www.soinside.com 2019 - 2024. All rights reserved.