当前位置: 首页 > 知识库问答 >
问题:

Java中的promise

尉迟明辉
2023-03-14

在提出问题之前,我最终要解决的问题是查询我的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,您可以生成一条user not found消息。

问题是,所有内容都在同一时刻运行,因此您总是会立即收到“未找到用户”消息,几秒钟后,侦听器可能会找到用户并说“欢迎回来”。

我一直在研究如何解决这个问题,我发现了Java的promise。我看的方向对吗?以下是两个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这样的东西。它只是说它无法解析符号。所以这家伙写了一篇关于一些根本不存在的东西的文章。

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

谢谢伙计们。请帮忙!

共有1个答案

顾穆冉
2023-03-14

使用异步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侦听器中设置Singleton属性值
  • Doug的优秀博文
  • 从Firebase查询数据
  • 等待Firebase异步在android中检索数据
  • 处理异步任务(Firebase)返回的数据
 类似资料:
  • 是否有在java中使用Promise(就像在JavaScript中使用ut一样)而不是使用嵌套回调的概念? 如果是这样,是否有一个在java中实现回调和链接处理程序的示例?

  • 问题内容: 我的问题可能太广泛了,答案可能是简单的“否”,但我不得不问。 Java 7中有(Java 8)流 *的等效实现吗? 我熟悉(Java 8)流,但是我的项目要求是使用Java 7。 *不要与inputStream和outputStream混淆。 问题答案: 在官方API中,没有。 Java 7没有更多的公共更新。如果您是客户,您可能仍然会获得较小的更新,但是对于反向移植Stream AP

  • 问题内容: 我正在寻找Java中的KeyValuePair类。 由于java.util大量使用接口,因此没有提供具体的实现,只有Map.Entry接口。 我可以导入一些规范的实现吗?这是我讨厌实现100倍的“管道工编程”类之一。 问题答案: 类AbstractMap.SimpleEntry是通用的,并且可能有用。

  • 问题内容: 我已经问过类似的问题,但是这次我将更具体。 我需要在一个循环中执行通常较大的正定对称矩阵(约)的Cholesky分解。现在,为此,我一直尝试: 1)Apache数学库 2)平行柯尔特库 3)JLapack库 在上述三种情况中的任何一种情况下,例如与MATLAB相比,时间消耗都非常长。 因此,我想知道Java中是否存在用于Cholesky分解的高度优化的外部工具:例如,我一直在思考CHO

  • 问题内容: Java 的用途是什么?有什么好处?它是如何工作的?示例代码也将很有用。 问题答案: 关键是要提供线程安全的实现。多个线程可以对其进行读写,而没有机会接收到过时或损坏的数据。 提供自己的同步,因此您不必显式同步对其的访问。 的另一个功能是它提供了该方法,如果指定的键不存在,它将 自动 添加一个映射。考虑以下代码: 此代码不是线程安全的,因为另一个线程可以在到和的调用之间添加映射。正确的

  • 问题内容: 在Java中调用R功能的最佳方法是什么? 我正在寻找一种使用我的Java应用程序在R中制作标准2d散点图和直方图的快速,简便和可靠的方法。我想知道快速Google搜索中出现的哪些程序包/界面最方便使用。 我期待您的建议! 问题答案: 使用JRI:http ://www.rforge.net/JRI/ 。它与rJava捆绑在一起,包括一些用法示例。 一个非常简单的示例如下: