AsyncWith.async

You're seeing just the macro async, go back to AsyncWith module for more information.
Link to this macro

async(with_expression, blocks \\ [])

View Source (macro)

Used to combine matching clauses, executing them asynchronously.

async with always executes the right side of each clause inside a new task. Tasks are spawned as soon as all the tasks that it depends on are resolved. In other words, async with resolves the dependency graph and executes all the clauses in the most performant way possible. It also ensures that, if a clause does not match, any running task is shut down.

Let's start with an example:

iex> opts = %{width: 10, height: 15}
iex> async with {:ok, width} <- Map.fetch(opts, :width),
...>            {:ok, height} <- Map.fetch(opts, :height) do
...>   {:ok, width * height}
...> end
{:ok, 150}

As in with/1, if all clauses match, the do block is executed, returning its result. Otherwise the chain is aborted and the non-matched value is returned:

iex> opts = %{width: 10}
iex> async with {:ok, width} <- Map.fetch(opts, :width),
...>            {:ok, height} <- Map.fetch(opts, :height) do
...>  {:ok, width * height}
...> end
:error

In addition, guards can be used in patterns as well:

iex> users = %{"melany" => "guest", "ed" => :admin}
iex> async with {:ok, role} when is_atom(role) <- Map.fetch(users, "ed") do
...>   :ok
...> end
:ok

Variables bound inside async with won't leak; "bare expressions" may also be inserted between the clauses:

iex> width = nil
iex> opts = %{width: 10, height: 15}
iex> async with {:ok, width} <- Map.fetch(opts, :width),
...>            double_width = width * 2,
...>            {:ok, height} <- Map.fetch(opts, :height) do
...>   {:ok, double_width * height}
...> end
{:ok, 300}
iex> width
nil

An else option can be given to modify what is being returned from async with in the case of a failed match:

iex> opts = %{width: 10}
iex> async with {:ok, width} <- Map.fetch(opts, :width),
...>            {:ok, height} <- Map.fetch(opts, :height) do
...>   {:ok, width * height}
...> else
...>   :error ->
...>     {:error, :wrong_data}
...> end
{:error, :wrong_data}

If an else block is used and there are no matching clauses, an AsyncWith.ClauseError exception is raised.

Order-dependent clauses that do not express their dependency via their used or defined variables could lead to race conditions, as they are executed in separated tasks:

async with Agent.update(agent, fn _ -> 1 end),
           Agent.update(agent, fn _ -> 2 end) do
  Agent.get(agent, fn state -> state end) # 1 or 2
end