Generators

Generators allow a function to pause its execution, hand control back to whoever called it, and then resume from where it left off. This is useful when a function does something repeatedly — like iterating through a loop — but the caller should decide what happens at each step. The function doesn't need to know the details; it just yields, and the caller handles it.

A common example is a function that loops 10 times. On each iteration, it yields to the caller. The caller might log a message, update a counter, return a mapped value, or do anything else. When the caller's handler finishes, the function picks up where it left off and continues to the next iteration.

The pink output trigger is a generator yield trigger. Notice that we don't loop back to the Map Gen function.
The `Map Gen` function - Notice the ping Generator node, which lets us yield once per iteration, and then resume with the returned value.

How it works

Inside a function, when flow reaches a generator's yield trigger, the function suspends. Execution then jumps out through the generators output trigger and runs whatever is connected to it. When that handler finishes, the function automatically resumes from the generator's resume trigger.

The function can yield as many times as it needs (for example, once per loop iteration), and eventually complete through a normal output trigger like done.

This is what it looks like when we add an instance of the function we defined above.

Adding a generator to a function

You can add a Generator node inside any function through the node menu (space bar). A generator node has three ports:

  • yield - a trigger input. When triggered, the function pauses and signals the caller.

  • resume - a trigger output. Fires when the caller's handler finishes, so the function can continue.

  • value - a data output. Contains the value passed back by the caller via a Resume node (see Passing values back on resume). This is null if no Resume node is used.

When you add a generator to a function, the function gets an additional output trigger that is visible to callers. This is the yield output - callers connect their handler to it.

Passing data out on yield

A function with a generator can send data to the caller each time it yields. Add output properties to the function and connect values to them as you normally would. When the function yields, the current values of all output properties are forwarded to the caller alongside the yield trigger. Since values are captured at each yield point, they can change across iterations.

On the caller side, read the function's output properties when the yield output fires. The values reflect whatever was connected inside the function at the time of the yield.

Passing values back on resume

The caller can also pass a value back into the function when it resumes, using a Resume node. You can add a `Resume` node from the node menu (space bar). It has two inputs:

  • resume - trigger to execute the resume operation.

  • value - the data to pass back into the yielded function.

The Resume node doesn't have an output trigger. Flow continues naturally through the rest of the handler, and the function resumes when the handler finishes.

Inside the function, read the generator's value output to access whatever the caller passed. If no Resume node was used, this is null.

For example, if the caller connects 42 to the Resume node's value input, the function will see 42 on the generator's value output when it resumes.

circle-info

You only need to use the Resume node if you want to pass a value back to the yielded function. Otherwise, you can just let the execution end in nothing, and the yielded function will automatically resume.

This is OK - no Resume node

Multiple generators

A function can contain more than one generator. Each generator has its own yield, resume, and value ports, and each creates its own yield output trigger on the function.

Inside the function, you can chain generators sequentially - connect the first generator's resume to the second generator's yield, and so on. On the caller side, each yield output can have its own handler and its own Resume node with a different value.

This lets a single function pause at multiple distinct points, with the caller handling each one independently.

Nesting generators

Generators can be nested across function boundaries. A yield handler in the caller can itself call another function that has a generator. When that inner function yields, its handler runs, and when it finishes, execution unwinds back through all the layers — each function resuming in turn.

Last updated

Was this helpful?