

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将数据传递到异步方法
<a name="advanceddatapassing"></a>

**Topics**
+ [将集合和映射传递到异步方法](#advanceddatapassing.collections)
+ [可设置 <T>](#advanceddatapassing.settable)
+ [@NoWait](#advanceddatapassing.nowait)
+ [承诺 < 撤消 >](#advanceddatapassing.promise)
+ [AndPromise 和 OrPromise](#advanceddatapassing.andorpromise)

在前几节中介绍了如何使用 `Promise<T>`。此处介绍 `Promise<T>` 的一些高级使用案例。

## 将集合和映射传递到异步方法
<a name="advanceddatapassing.collections"></a>

该框架支持将数组、集合和映射作为 `Promise` 类型传递到异步方法。例如，异步方法可以将 `Promise<ArrayList<String>>` 作为参数，如以下列表所示。

```
@Asynchronous
public void printList(Promise<List<String>> list) {
    for (String s: list.get()) {
        activityClient.printActivity(s);
    }
}
```

从语义地讲，它与任何其他 `Promise` 类型的参数类似，异步方法将等到集合变为可用，然后再执行。如果集合成员是 `Promise` 对象，您可以让该框架等待所有成员变为就绪状态，如以下代码段所示。这会使异步方法等待集合的每个成员变为可用。

```
@Asynchronous
public void printList(@Wait List<Promise<String>> list) {
  for (Promise<String> s: list) {
      activityClient.printActivity(s);
  }
}
```

 请注意，必须在参数中使用 `@Wait` 注释以指示它包含 `Promise` 对象。

 另请注意，活动 `printActivity` 使用 `String` 参数，但生成的客户端中的匹配方法使用 Promise<String>。我们将调用客户端上的方法，而不是直接调用活动方法。

## 可设置 <T>
<a name="advanceddatapassing.settable"></a>

`Settable<T>` 是 `Promise<T>` 的派生类型，它提供一个设置方法以允许手动设置 `Promise` 值。例如，以下工作流程等待 `Settable<?>` 以等待接收信号，后者是在信号方法中设置的：

```
public class MyWorkflowImpl implements MyWorkflow{
   final Settable<String> result = new Settable<String>();

   //@Execute method
   @Override
   public Promise<String> start() {
      return done(result);
   }

   //Signal
   @Override
   public void manualProcessCompletedSignal(String data) {
      result.set(data);
   }

   @Asynchronous
   public Promise<String> done(Settable<String> result){
       return result;
   }
}
```

每次还可以将一个 `Settable<?>` 链接到另一个 promise。您可以使用 `AndPromise` 和 `OrPromise` 对 promise 进行分组。您可以在链接的 `Settable` 上调用 `unchain()` 方法以将其取消链接。在链接后，在链接的 promise 变为就绪状态时，`Settable<?>` 自动变为就绪状态。如果要在程序的其他部分中使用从 `doTry()` 作用域中返回的 promise，链接是特别有用的。`TryCatchFinally`因为用作嵌套类，所以你不能在父级的作用域`Promise<>`中声明 a 并将其设置在中`doTry()`。这是因为，Java 要求在父类作用域中声明变量，并在嵌套类中使用变量以标记为 final。例如：

```
@Asynchronous
public Promise<String> chain(final Promise<String> input) {
    final Settable<String> result = new Settable<String>();

    new TryFinally() {

        @Override
        protected void doTry() throws Throwable {
            Promise<String> resultToChain = activity1(input);
            activity2(resultToChain);

            // Chain the promise to Settable
            result.chain(resultToChain);
        }

        @Override
        protected void doFinally() throws Throwable {
            if (result.isReady()) { // Was a result returned before the exception?
                // Do cleanup here
            }
        }
    };

    return result;
}
```

每次可以将一个 `Settable` 链接到一个 promise。您可以在链接的 `Settable` 上调用 `unchain()` 方法以将其取消链接。

## @NoWait
<a name="advanceddatapassing.nowait"></a>

在将 `Promise` 传递到一个异步方法时，默认情况下，该框架等待 `Promise` 变为就绪状态，然后再执行该方法 (集合类型除外)。您可以在异步方法声明中的参数上使用 `@NoWait` 注释以覆盖该行为。如果传入 `Settable<T>` (异步方法本身将对其进行设置)，这是非常有用的。

## 承诺 < 撤消 >
<a name="advanceddatapassing.promise"></a>

异步方法中的依赖关系是通过将一个方法返回的 `Promise` 作为参数传递到另一个方法实现的。但在某些情况下，您希望从一个方法中返回 `void`，但仍希望其他异步方法在该方法完成后执行。在这些情况下，您可以将 `Promise<Void>` 作为方法的返回类型。`Promise` 类提供了一个静态 `Void` 方法，可用于创建 `Promise<Void>` 对象。在异步方法完成执行时，该 `Promise` 将变为就绪状态。您可以将该 `Promise` 传递到另一个异步方法，就像任何其他 `Promise` 对象一样。如果您使用 `Settable<Void>`，则使用 null 在其上调用设置方法以使其变为就绪状态。

## AndPromise 和 OrPromise
<a name="advanceddatapassing.andorpromise"></a>

通过使用 `AndPromise` 和 `OrPromise`，您可以将多个 `Promise<>` 对象划分到单个逻辑 promise。在用于构建 `AndPromise` 的所有 promise 变为就绪状态时，它将变为就绪状态。在用于构建 `OrPromise` 的 promise 集合中的任何 promise 变为就绪状态时，它将变为就绪状态。您可以在 `AndPromise` 和 `OrPromise` 上调用 `getValues()` 以检索组成 promise 的值列表。