9

我知道Function的apply方法同步返回一个对象,AsyncFunction的apply异步运行,返回一个Future。

你能给我一个什么时候喜欢什么的例子吗?

我看到的一个代码片段看起来像这样:

Futures.transform(someFuture, new AsyncFunction<A, B>() {
  public B apply(A a) {
    if (a != null) {
      return Futures.immediateFuture(a.getData())
    } else {
      return Futures.immediateFailedFuture(checkException(());
    }
  });
});

既然 AsyncFunction 内部的值作为立即结果返回,为什么这里需要 AsyncFunction 呢?或者这只是我遇到的一个坏例子?

4

4 回答 4

10

您找到的代码片段是一个不好的示例,因为它使用 AsyncFunction 来处理同步计算的内容。这是不必要的冗长。

使用标准代码会更干净Function

Futures.transform(someFuture, new Function<A, B>() {
  public B apply(A a) {
    if (a != null) {
      return a.getData();
    } else {
      throw checkException();
    }
  });
});

AsyncFunction当将 A 转换为 B 的代码是异步的时,您应该使用a。在您的示例中,代码一开始可能是异步的,后来被不费心用 . 替换的程序员更改为使用Futures.immediateFuture()/ 。或者也许他只是错过了重载的方法。Futures.immediateFailedFuture()AsyncFunctionFunction

于 2014-06-05T15:45:09.777 回答
3

既然 AsyncFunction 内部的值作为立即结果返回,为什么这里需要 AsyncFunction 呢?或者这只是我遇到的一个坏例子?

小心。那段代码正在生成一个匿名类的实例并将该实例传递给该transform方法。该transform方法将使用AsyncFunction一个单独的线程。Future返回的链从 中检索结果AsyncFunction并返回 that 的结果Future。这段代码仍然涉及异步处理。

在需要时使用异步处理,并且可以在执行其他操作时继续工作。

于 2014-06-05T00:27:14.080 回答
1

你给出的代码片段是一个不好的例子,写它的人应该使用函数。

Futures.transform() 用于跟进一些异步过程。让我们将其称为“异步进程 1”的“ap1”。当 ap1 完成后,由 transform 链接的函数将执行。现在,让我们讨论可以与 Futures.transform() 链接的 2 种类型的函数。

    // AsyncFunction() example:
    ListenableFuture<B> future2 = Futures.transform(future1, new AsyncFunction<A, B>() {
      public ListenableFuture<B> apply(A a) {
        if (a != null) {
          ListenableFuture<B> future3 = asyncCallToOtherService(a);
          return future3;
        }
        else {
          return Future.immediateFuture(null);
        }
      });
    });

    // more complex AsyncFunction() example:
    ListenableFuture<B> future2 = Futures.transform(future1, new AsyncFunction<A, B>() {
      public ListenableFuture<B> apply(A a) {
        if (a != null) {
          ListenableFuture<C> future3 = asyncCallToOtherService(a);
          return Futures.transform(future3, new Function<C, B>() {
            @Override
            public B apply(C c) {
              B b = new B();
              b.setResult(c.getStatus());
              return b;
            }
          });
        }
        else {
          return Future.immediateFuture(null);
        }
      });
    });

    // Function() example:
    ListenableFuture<B> future2 = Futures.transform(future1, new Function<A, B>() {
      public B apply(A a) {
        if (a != null) {
          B b = new B();
          b.setResult(a.getStatus());
          return b;
        }
        else {
          return null;
        }
      });
    });
  1. 当 apply() 中的代码产生另一个异步进程 2 (AP2) 时,应使用 AsyncFunction()。这形成了一系列相互跟随的异步调用:AP1->AP2。
  2. 当从 AP1 转换结果不需要任何额外的异步过程时,应使用 Function()。相反,它所做的只是以同步方式将结果 Object1 转换为其他 Object2。
  3. AsyncFunction() 稍微重一些并且导致单独的线程,因此我们应该在不需要旋转 AP2 时使用 Function()。
  4. 可以根据需要将多个函数和 AsyncFunction 链接在一起,以形成完整的工作流程。示例“更复杂的 AsyncFunction() 示例”链接 A~>C->B 转换,其中 A~>C 是异步的。
于 2016-06-23T17:43:40.533 回答
1

在这里使用 AsyncFunction 是有意义的。如果您想从 Function 中的 apply() 方法中抛出一些已检查的异常,它会抱怨它没有被处理。您不能将其从 apply() 中丢弃,因为它已被覆盖。所以如果你想抛出一些检查异常,AsyncFunction 应该是一个有效的解决方案。对于那些说给定示例不好并且给定函数示例的人,您可以尝试编译它吗?

于 2017-07-13T01:23:19.177 回答