

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 將資料傳遞給非同步方法
<a name="advanceddatapassing"></a>

**Topics**
+ [將集合和對應傳遞給非同步方法](#advanceddatapassing.collections)
+ [Settable<T>](#advanceddatapassing.settable)
+ [@NoWait](#advanceddatapassing.nowait)
+ [Promise<Void>](#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>。我們會在用戶端上呼叫此方法，而不是直接呼叫活動方法。

## Settable<T>
<a name="advanceddatapassing.settable"></a>

`Settable<{{T}}>` 是 `Promise<T>` 的衍生類型，提供 set 方法讓您手動設定 `Promise` 的值。例如，下列工作流程透過等待 `Settable<?>` 來等待收到訊號，此於 signal 方法中設定：

```
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()` 方法，以將其取消鏈結。鏈結時，`Settable<?>` 會在其鏈結的 Promise 就緒時自動變成就緒。當您想要在程式的其他部分中使用從 `doTry()` 範圍內傳回的 Promise 時，鏈結會特別有用。由於 `TryCatchFinally` 用作巢狀類別，因此您無法`Promise<>`在父系範圍內宣告 ，並在 中設定它`doTry()`。原因是 Java 需要在父範圍中宣告變數，並用於要標示為最終的巢狀類別。例如：

```
@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>`，這會十分有用。

## Promise<Void>
<a name="advanceddatapassing.promise"></a>

非同步方法中相依性的實作方式是將某個方法所傳回的 `Promise` 以引數傳遞給另一個方法。不過，您可能會想要從方法傳回 `void`，但仍想要其他非同步方法於其完成後再執行。在這種情況下，您可以使用 `Promise<Void>` 做為方法的傳回類型。`Promise` 類別提供靜態 `Void` 方法，能讓您用以建立 `Promise<Void>` 物件。非同步方法完成執行時，此 `Promise` 會就緒。您可以將此 `Promise` 傳遞給另一個非同步方法，如同其他 `Promise` 物件。如果您使用 `Settable<Void>`，則請在其上以 null 呼叫 set 方法，使之就緒。

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

`AndPromise` 和 `OrPromise` 可讓您將多個 `Promise<>` 物件分組為單一邏輯 Promise。`AndPromise` 會在用來建構它的所有 Promise 都就緒時就緒。`OrPromise` 會在用來建構它的 Promise 集合中的任何 Promise 都就緒時就緒。您可以對 `AndPromise` 和 `OrPromise` 呼叫 `getValues()`，以擷取組成 Promise 之值的清單。