Sync vs Async
arkffi’s default C function calls are synchronous —lib.symbols.add(2.0, 3.0) blocks the current thread until the function returns.
For expensive operations (complex computation, I/O), use callAsync to offload the call to a libuv worker thread and get a Promise back.
ffi.callAsync
Syntax
Parameters
| Parameter | Type | Description |
|---|---|---|
handle | bigint | Library handle from ffi.load() |
funcName | string | Function name (must be registered via defineFunction) |
argTypes | string | Argument type codes |
returnType | string | Return type code |
numArgs | number[] | Numeric arguments |
strArgs | string[] | String arguments |
AsyncCFunction
AsyncCFunction is the async counterpart of CFunction with the same signature, returning Promise<number>. No defineFunction needed — works directly with function pointers:
Comparison
| Feature | CFunction | AsyncCFunction |
|---|---|---|
| Returns | number (sync) | Promise<number> (async) |
| Blocks main thread | ✅ Yes | ❌ No |
Needs defineFunction | ❌ No | ❌ No |
| Type support | All | All |
| Close method | .close() | .close() |
Usage with dlopen
Functions must be registered via defineFunction before making async calls:
Implementation
callAsyncparses arguments on the JS thread and creates anapi_async_work- The worker thread executes
DispatchCallRaw— a pure C function pointer call with no NAPI involvement - On completion, the Promise is resolved on the JS thread
- The JS main thread is never blocked
Limitations
- String return types are not supported (no async version of
callString) - Callbacks (
JSCallback) cannot be invoked from the async worker thread - The function must be registered via
defineFunctionfirst