% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/async.R
\name{async}
\alias{async}
\title{Wrap a message handler to run asynchronously with zero configuration}
\usage{
async(
  fn,
  app = NULL,
  loading_message = "Working...",
  cancellable = TRUE,
  error_message = "Error: "
)
}
\arguments{
\item{fn}{The handler function, taking a \code{payload} argument.}

\item{app}{The RDesk \code{App} instance. If NULL, tries to resolve from the global registry.}

\item{loading_message}{Message to display in the UI overlay while working.}

\item{cancellable}{Whether the UI should show a 'Cancel' button.}

\item{error_message}{Prefix for toast notifications if the task fails.}
}
\value{
A wrapped handler function suitable for \code{app$on_message()}.
}
\description{
\code{async()} is the simplest way to make an RDesk message handler
non-blocking. Wrap any handler function with \code{async()} and RDesk
automatically handles background execution, loading states, error toasts,
and result routing.

\code{async()} transforms a standard RDesk message handler into a background task.
The UI remains responsive while the task runs. When finished, a result
message (e.g., \code{get_data_result}) is automatically sent back to the UI.
}
\details{
To ensure the background worker has access to all application logic, RDesk
automatically sources every \code{.R} file in the application's \verb{R/} directory
before executing the task. It also snapshots currently loaded packages
(excluding system packages) to recreate the environment.
}
\examples{
if (interactive()) {
  app$on_message("filter_cars", async(function(payload) {
    mtcars[mtcars$cyl == payload$cylinders, ]
  }, app = app))
}
}
