Skip to main content

runWhile

workflow.runWhile() is the built-in while loop execution node. It executes condition before the start of each round, executes the loop body run when the condition is true, and returns the value as the state of the next round. The runtime will emit start/finish events for branch-node, and Desktop Diagram will wrap the loop body node in a loop container with a background color.

Signature

workflow.runWhile<State>(
input: State,
context: WorkflowContext,
options: {
name?: string;
condition(input: State, context: WorkflowContext, iteration: number): boolean | Promise<boolean>;
run(input: State, context: WorkflowContext, iteration: number): State | Promise<State>;
maxIterations?: number;
metadata?: Partial<WorkflowNodeMetadata>;
},
): Promise<State>

Parameter

ParameterTypeDescription
inputStateInitial cycle state.
contextWorkflowContextruntime context for hooks, provider, KV, files, abortSignal.
options.namestringDiagram and the loop node titles displayed in the Trace. Default Run while.
options.conditionfunctionExecute before start of each round; continue loop when return true. The third argument is the iteration starting at 0.
options.runfunctionThe body of the loop executed after the condition is hit, returning to the next round.
options.maxIterationsnumberThe maximum number of iterations. Default 100 to prevent accidental infinite loops.
options.metadataPartial<WorkflowNodeMetadata>Overwrites the metadata of loop nodes; by default, the type is run-while.

Operation Report

runWhile Use the standard node name run-while, and run with kind branch-node. The executionInfo that completes the event will include:

{
"loopType": "while",
"iterations": 2,
"iterationCount": 2,
"maxIterations": 100,
"completed": true
}

completed is false on failure and retains the number of iterations that have completed.

Example

const finalState = await workflow.runWhile(seed, context, {
name: "Boost until target",
maxIterations: 8,
condition: (state) => state.total < state.target,
async run(state, loopContext, iteration) {
return workflow.runIf(state, loopContext, {
name: "Choose boost strategy",
branches: [
{
label: "burst",
condition: (current) => current.target - current.total >= 7,
async run(current, branchContext) {
return workflow.runFor(current, branchContext, {
name: "Burst passes",
maxIterations: 3,
items: () => [4, 3],
async run(passState, value, index, passContext) {
return workflow.runNode(boostNode, { ...passState, value, index, iteration }, passContext);
},
});
},
},
],
else: {
label: "finish",
async run(current, branchContext) {
return workflow.runNode(boostNode, { ...current, iteration }, branchContext);
},
},
});
},
});

Diagram

Static structural analysis identifies object literals in the forms of condition, maxIterations, and run. In run, workflow.runNode, workflow.runStreamNode, workflow.runIf, workflow.runFor, and workflow.runWhile will become loop body nodes and will be enclosed by the loop container in Desktop Diagram. To ensure Diagram remains readable, the loop configuration should preferably be kept as an object literal; dynamically constructing the options is still feasible, but the static diagram can only display limited information.

Error

SituationError TypeDescription
More than maxIterationsnode_executionThrow out Run-while node "<name>" exceeded maxIterations (<value>)..
condition or run throws an errornode_executionThe original error is wrapped as WorkflowError and written to the loop node report.
Break before execution or in a loopexecution_aborted or node_executionFrom context.abortSignal.