@async annotation marks functions as asynchronous, providing hints to the IDE and developers that a function performs asynchronous operations using coroutines or async/await patterns.
Syntax
Why Mark Functions as Async?
The@async annotation helps:
- Document intent: Clearly shows which functions are asynchronous
- IDE support: Enables async-aware analysis and warnings
- Type checking: Validates async/await patterns
- Developer guidance: Warns when async functions are called incorrectly
Basic Async Functions
---@async
---@param url string Request URL
---@return string Response content
function fetchData(url)
return coroutine.wrap(function()
print("Starting request:", url)
-- Simulate network delay
local co = coroutine.running()
timer.setTimeout(function()
coroutine.resume(co, "Response data: " .. url)
end, 1000)
return coroutine.yield()
end)()
end
-- Usage
local data = fetchData("https://api.example.com/users")
print("Received:", data)
---@async
---@param filepath string File path
---@return string File content
function readFileAsync(filepath)
return coroutine.wrap(function()
local file = io.open(filepath, "r")
if not file then
error("Cannot open file: " .. filepath)
end
local content = file:read("*a")
file:close()
-- Simulate async reading
coroutine.yield()
return content
end)()
end
---@async
---@param filepath string File path
---@param content string Content to write
---@return boolean success Whether write succeeded
function writeFileAsync(filepath, content)
return coroutine.wrap(function()
local file = io.open(filepath, "w")
if not file then
return false
end
file:write(content)
file:close()
-- Simulate async writing
coroutine.yield()
return true
end)()
end
---@async
---@param query string SQL query
---@return table[] Query results
function queryDatabase(query)
return coroutine.wrap(function()
print("Executing query:", query)
-- Simulate database connection and query
local co = coroutine.running()
database.execute(query, function(results)
coroutine.resume(co, results)
end)
return coroutine.yield()
end)()
end
Error Handling in Async Functions
Async/Await Pattern
Chaining Async Operations
Parallel Async Operations
Before/After Comparison
Without @async
- No indication of async behavior
- Easy to misuse async functions
- No IDE warnings
- Unclear control flow
With @async
- Clear async markers
- IDE understands async flow
- Proper warnings for misuse
- Self-documenting code
Real-World Example
Best Practices
Always mark coroutine-based functions as @async
Always mark coroutine-based functions as @async
Any function that uses
coroutine.yield() or returns a coroutine should be marked @async.Mark calling functions as @async too
Mark calling functions as @async too
If a function calls an async function, it should also be marked
@async.Handle errors in async operations
Handle errors in async operations
Use
pcall or return error values to handle async failures gracefully.Document return types clearly
Document return types clearly
Async functions should clearly document what they return, especially Promise or coroutine types.
Be consistent with async patterns
Be consistent with async patterns
Choose one async pattern (callbacks, coroutines, or promises) and use it consistently.
Common Async Patterns
Timeout Pattern
Retry Pattern
See Also
- @param - Document function parameters
- @return - Document return values
- Coroutines Guide - Official Lua coroutine documentation
