Async

Async values are created with the $async function, which wraps a promise-returning getter. While the promise is pending, reads of the getter suspend (and read as undefined, hence the optional chaining):


export default function Component($props: { id: number }) {
	let $state = $watch({
		get user() {
			return $async(() => fetchUser($props.id))
		}
	})

	@render {
		<p>
			Hello, {$state.user?.name}!
		</p>
	}
}

Await statements

Use an @await statement to show a with branch while suspended, and the content branch when everything has resolved:


export default function Component($props: { id: number }) {
	let $state = $watch({
		get user() {
			return $async(() => fetchUser($props.id))
		}
	})

	@render {
		@await {
			<p>
				Hello, {$state.user?.name}!
			</p>
		} with {
			<p>Loading...</p>
		}
	}
}

Without a with branch, nothing is rendered while suspended. Once content has rendered, a later suspend keeps the existing content mounted rather than flashing back to the with branch.

The $pending function

The $pending function returns true while any $async getter read within it is loading, which is useful for showing a loading indicator inline:


<button disabled={$pending(() => $state.user)}>
	Save
</button>
@if ($pending(() => $state.user)) {
	<p>Loading...</p>
}

The $refresh function

The $refresh function re-runs the $async getters read within it, without a dependency having changed. Use it for refresh buttons, polling and retry-after-error:


export default function Component() {
	let $state = $watch({
		get data() {
			return $async(() => fetchData())
		}
	})

	function refresh() {
		$refresh(() => $state.data)
	}

	@render {
		<button onclick={refresh}>
			Refresh
		</button>
		<p>
			{$state.data.message}
		</p>
	}
}

A refresh is loud by default: $pending returns true while it is in flight. Pass { silent: true } for a quiet re-fetch, e.g. for polling in the background.

When an async value throws, the error can be caught with a @try statement — see Errors.

Server rendering

$async getters currently run on the client: the server renders the @await with branch, and fetching starts after the page hydrates. Coming soon: an opt-in source: "server" mode, where the server fetches during render and delivers the result with the page (by await-and-embed first, with streaming delivery to follow).