Performing I/O operations and side effects in Bubble Tea
Commands (Cmds) are how Bubble Tea handles I/O operations and side effects. They’re functions that run asynchronously and return messages when they complete.
// Cmd is an IO operation that returns a message when it's complete. If it's// nil it's considered a no-op. Use it for things like HTTP requests, timers,// saving and loading from disk, and so on.//// Note that there's almost never a reason to use a command to send a message// to another part of your program. That can almost always be done in the// update function.type Cmd func() Msg
A command is simply a function that returns a message. That’s it!Commands run asynchronously in goroutines, allowing your UI to remain responsive while I/O operations happen in the background.
Run multiple commands concurrently with no ordering guarantees.From commands.go:7-17:
// Batch performs a bunch of commands concurrently with no ordering guarantees// about the results. Use a Batch to return several commands.func Batch(cmds ...Cmd) Cmd
// Sequence runs the given commands one at a time, in order. Contrast this with// Batch, which runs commands concurrently.func Sequence(cmds ...Cmd) Cmd
Example:
func (m model) login() tea.Cmd { return tea.Sequence( authenticate(), // Wait for auth fetchUserProfile(), // Then get profile loadPreferences(), // Then load prefs )}
With Sequence, if any command returns QuitMsg, the remaining commands won’t run.
// Tick produces a command at an interval independent of the system clock at// the given duration. That is, the timer begins precisely when invoked,// and runs for its entire duration.func Tick(d time.Duration, fn func(time.Time) Msg) Cmd
Example:
type tickMsg time.Timefunc (m model) Init() tea.Cmd { return tea.Tick(time.Second, func(t time.Time) tea.Msg { return tickMsg(t) })}func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tickMsg: m.counter++ // Schedule next tick return m, tea.Tick(time.Second, func(t time.Time) tea.Msg { return tickMsg(t) }) } return m, nil}
Beginner’s note:Tick sends a single message. To create a repeating timer, return another Tick command when you receive the tick message.
Create a timer that syncs with the system clock.From commands.go:56-114:
// Every is a command that ticks in sync with the system clock. So, if you// wanted to tick with the system clock every second, minute or hour you// could use this.func Every(duration time.Duration, fn func(time.Time) Msg) Cmd
Example:
// Update the clock display on the minutefunc (m model) Init() tea.Cmd { return tea.Every(time.Minute, func(t time.Time) tea.Msg { return clockUpdateMsg(t) })}