Skip to content

Async ​

Async resources: a fetcher runs off the graph, and its progress is exposed as nodes (data, error, loading, state). A race guard keeps only the latest fetch's result.

luau
local profile = Flux.async(userId, function(id) return fetchProfile(id) end)

Constructors: Async.new

Types ​

AsyncState type ​

luau
type AsyncState = "unresolved" | "pending" | "ready" | "refreshing" | "errored"

The state of an async node, derived from its .error/.loading and whether a fetch has resolved.

  • unresolved (nothing fetched yet)
  • pending (first fetch in flight, no value)
  • refreshing (fetch in flight over an existing value)
  • ready (resolved)
  • errored (last fetch threw)

Async type ​

luau
type Async<T> = {
	data: Graph.Node<T?>,
	error: Graph.Node<string?>,
	loading: Graph.Node<boolean>,
	state: Graph.Node<AsyncState>,
	--[[
	Destroys the async node, cleaning up all resources.
	[Open Documentation](https://flux.kohl.gg/guide/concepts/async)
	]]
	Destroy: (self: any) -> (),
	--[[
	Re-runs the fetcher with the current source value without writing the source node.
	An optional `refetching` payload is forwarded to the fetcher (defaults to `true`).
	[Open Documentation](https://flux.kohl.gg/guide/concepts/async)
	]]
	refetch: (self: any, refetching: any?) -> (),
	--[[
	Optimistically writes `data` and invalidates any in-flight fetch.
	[Open Documentation](https://flux.kohl.gg/guide/concepts/async)
	]]
	mutate: (self: any, value: T) -> (),
}

Functions ​

new ​

luau
Async.new(source: any, fetcher: any, initialValue: any): Async<any>

Creates a non-blocking asynchronous node that runs yielding work off the reactive graph and exposes its progress as four nodes: .data (seeded with initialValue before the first fetch resolves), .error, .loading, and .state. source is a tracked input (a node or computation) whose value is passed to fetcher and re-runs it on every change; omit source and pass fetcher first for a one-shot fetch, or let source evaluate to nil/false to gate the fetch off until it turns truthy. fetcher(value, previous, refetching) runs untracked (where previous is the last resolved data and refetching flags a manual refetch, so reactive reads inside it are not tracked as dependencies), and a race guard discards stale results so only the latest fetch ever writes back.

luau
local profile = Flux.async(userId, function(id) return Players:GetNameFromUserIdAsync(id) end)
Flux.new "TextLabel" { Text = function() return profile.data() or "Loading" end }

Open Documentation

Methods ​

Destroy ​

luau
Async:Destroy()

Destroys the async node, cleaning up all resources.

Open Documentation

mutate ​

luau
Async:mutate(value: any)

Optimistically writes data and invalidates any in-flight fetch.

Open Documentation

refetch ​

luau
Async:refetch(refetching: any?)

Re-runs the fetcher with the current source value without writing the source node. An optional refetching payload is forwarded to the fetcher (defaults to true).

Open Documentation