Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Async/Await in Lykn

Async/await is syntactic sugar over promises. async makes a function return a promise. await pauses execution until a promise settles.

async as a Wrapper

In Lykn, async wraps any function form — func, fn, lambda:

(async (func fetch-user
  :args (:string id)
  :body
  (bind response (await (fetch (template "/api/users/" id))))
  (await (response:json))))
async function fetchUser(id) {
  if (typeof id !== "string")
    throw new TypeError(
      "fetch-user: arg 'id' expected string, got " + typeof id);

  const response = await fetch(`/api/users/${id}`);
  return await response.json();
}

async sets async: true on the compiled function. Type checks, contracts, everything else works the same — it’s just an async function now.

Async fn

(bind handler (async (fn (:any event)
  (bind data (await (fetch-data)))
  (process data))))
const handler = async (event) => {
  const data = await fetchData();
  process(data);
};

await Is Unary

(await expr) compiles to await expr. It can only appear inside an async function — or at the top level of a module.

Top-Level Await

Because all Lykn code is ESM, await works at the top level without wrapping in async:

(bind config (await (load-config "app.json")))
(bind db (await (connect config:database-url)))
(console:log "Ready")
const config = await loadConfig("app.json");
const db = await connect(config.databaseUrl);
console.log("Ready");

No async wrapper needed. The module itself is the async context. This is one of the quiet benefits of ESM-only — top-level await is free.