---
title: "Waits"
description: "WaitFor returns a Wait with a wait type and the conditions to wait for."
canonical_url: "https://docs.superdurable.io/reference/go/1.37.x/flows-and-steps/waits/"
source: "docs/reference-go_versioned_docs/version-1.37.x/flows-and-steps/waits.mdx"
locale: "en"
---

# Waits

**WaitFor** returns a **Wait** with a wait type and the conditions to wait for.
Dex persists the waiting state and evaluates the conditions when related state
changes. [Timer](https://docs.superdurable.io/concepts/primitives/timer.md), [Channel](https://docs.superdurable.io/concepts/primitives/channel.md), and
[SubFlow](https://docs.superdurable.io/concepts/primitives/subflow.md) are the condition kinds.

- **Until** waits for one condition.
- **AnyOf** is met when any condition is met.
- **AllOf** is met when all conditions are met.
- **AnyCombinationOf** is met when any one group of conditions is all met.

**Until**, **AnyOf**, and **AllOf** accept Conditions without condition IDs. Do
not add IDs merely because a Condition is nested in one of these waits. Read
Channel results from the Channel definition and inspect Timer outcomes through
the **Context**. Add IDs only when another API requires them, such as
**AnyCombinationOf** or a Timer selected by ID.

```go
return dex.AnyOf(
	SignalA.ForOne(),
	dex.Timer(timeout),
), nil
```

Example: [examples/go/primitives/wait-types/workflow.go](https://github.com/superdurable/dex/tree/main/examples/go/primitives/wait-types/workflow.go)

```go
return dex.AllOf(
	SignalA.ForOne(),
	SignalB.ForOne(),
), nil
```

Example: [examples/go/primitives/wait-types/workflow.go](https://github.com/superdurable/dex/tree/main/examples/go/primitives/wait-types/workflow.go)

<a id="condition-results"></a>

## Condition results

After **WaitFor** completes, **Execute** can read what satisfied the Wait. For a
[Channel](https://docs.superdurable.io/concepts/primitives/channel.md), use **GetConditionResults** / **results** /
**condition_results** to read published messages. For a
[SubFlow](https://docs.superdurable.io/concepts/primitives/subflow.md), use **SubFlowResult** / **getConditionResults**
/ **condition_result** to decode the child Flow output.

Channel consumption is not greedy across **AnyOf** alternatives. Dex consumes
messages only from the Channel condition selected to satisfy the Wait. Other
Channel conditions consume nothing even if they are also ready, so their
messages remain queued.

When several **AnyOf** alternatives are ready in one evaluation, Dex selects
the first feasible candidate in canonical order: Timer conditions in
declaration order, then Channel conditions in declaration order, then SubFlow
conditions in declaration order. An earlier condition that is not ready does
not block a later ready condition. Mixed condition kinds therefore do not share
one global call argument order.

Use **AnyOf** for a race among the current alternatives. For strict priority
that must keep waiting for a higher-priority input, return only that condition
until it is resolved.

<a id="channel-结果"></a>

<a id="channel-results"></a>

### Channel results

```go
var Approval = dex.DefineChannel[string]("Approval")

type channelWait struct {
	dex.StepDefaults
}

func (channelWait) WaitFor(_ dex.Context, input int) (*dex.Wait, error) {
	return dex.AnyOf(
		Approval.ForOne(),
		dex.Timer(time.Duration(input)*time.Second),
	), nil
}

func (channelWait) Execute(ctx dex.Context, _ int) (*dex.StepDecision, error) {
	if ctx.HasTimerFired() {
		return dex.GracefulComplete("approval timed out"), nil
	}
	results, err := Approval.GetConditionResults(ctx)
	if err != nil {
		return nil, err
	}
	return dex.GracefulComplete(results[0]), nil
}
```

Example: [examples/go/primitives/channel/workflow.go](https://github.com/superdurable/dex/tree/main/examples/go/primitives/channel/workflow.go)

<a id="subflow-结果"></a>

<a id="subflow-results"></a>

### SubFlow results

```go
func (subFlowParent) Execute(ctx dex.Context, _ int) (*dex.StepDecision, error) {
	result, err := dex.SubFlowResult(ctx)
	if err != nil {
		return nil, err
	}
	var output int
	if err := result.DecodeSingleOutput(&output); err != nil {
		return nil, err
	}
	flowID, err := dex.SubFlowID(ctx)
	if err != nil {
		return nil, err
	}
	return dex.GracefulComplete(fmt.Sprintf("%s|%d", flowID, output)), nil
}
```

Example: [examples/go/primitives/subflow/parent_flow.go](https://github.com/superdurable/dex/tree/main/examples/go/primitives/subflow/parent_flow.go)

<a id="anycombinationof"></a>

## AnyCombinationOf

**AnyCombinationOf** expresses an OR of AND groups. Build each inner group as
an all-of combination.

Channel consumption is not greedy across combinations. Dex consumes messages
only from Channel conditions in the selected combination. Conditions belonging
only to other ready combinations consume nothing, so their messages remain
queued.

Every Condition in its combinations requires a unique **condition ID**.

```go
return dex.AnyComboOf(
	dex.Combo(
		SignalA.ForOne(dex.WithConditionID("signal-a")),
		dex.Timer(timeout, dex.WithConditionID("timeout")),
	),
	dex.Combo(
		SignalB.ForOne(dex.WithConditionID("signal-b")),
	),
), nil
```

Example: [examples/go/primitives/wait-types/workflow.go](https://github.com/superdurable/dex/tree/main/examples/go/primitives/wait-types/workflow.go)

<a id="step-execution-local"></a>

## Step execution local

**SetStepExecutionLocal** stores a value on this **StepExecution** so
**Execute** can read it with **GetStepExecutionLocal**. Use it when **WaitFor**
computes something **Execute** needs but a Flow-level **Attribute** is
overkill. Step input is already passed to both methods. Do not copy input into
a local.

```go
func (noteWait) WaitFor(ctx dex.Context, input int) (*dex.Wait, error) {
	if err := ctx.SetStepExecutionLocal("note", fmt.Sprintf("approval:%d", input)); err != nil {
		return nil, err
	}
	return dex.Until(Approval.ForOne()), nil
}

func (noteWait) Execute(ctx dex.Context, _ int) (*dex.StepDecision, error) {
	var note string
	found, err := ctx.GetStepExecutionLocal("note", &note)
	if err != nil {
		return nil, err
	}
	if !found {
		return nil, fmt.Errorf("note was not set")
	}
	return dex.GracefulComplete(note), nil
}
```

Example: [examples/go/primitives/step-execution-local/workflow.go](https://github.com/superdurable/dex/tree/main/examples/go/primitives/step-execution-local/workflow.go)

<a id="skip-immediately"></a>

## Skip immediately

**SkipWaitImmediately** waits for no condition. Use it in a dynamic **WaitFor**
method when one branch must not wait for anything.

```go
return dex.SkipWaitImmediately(), nil
```

Example: [examples/go/primitives/flow/workflow.go](https://github.com/superdurable/dex/tree/main/examples/go/primitives/flow/workflow.go)
