template<typename T = void>
class ultralight::js::Task< T >
A coroutine that returns a JavaScript Promise to the page.
A Task is a C++20 coroutine. Returning one from a bound function gives the page a JavaScript Promise that settles during a later Renderer::Update() after the coroutine finishes.
The coroutine executes sequentially from top to bottom, pausing at each co_await without blocking the Renderer's thread.
Return a Task from a bound function to perform background work and return a Promise:
SaveData data =
if (!data.valid)
co_return data;
};
static Error Make(ErrorType type, std::string message)
Create a native error of any type.
Definition Error.h:168
Error WithCode(std::string code) &&
Add a code that page script gets as the error's code property when it's thrown.
Definition Error.h:234
A coroutine that returns a JavaScript Promise to the page.
Definition Task.h:112
auto RunOnWorker(Fn &&fn)
Run a function on a background thread, then resume the coroutine on the Renderer's thread with its re...
Definition Task.h:263
@ Error
A plain Error, or an error type with no dedicated constant.
Definition Error.h:55
Page script awaits the returned Promise normally:
const save = await app.loadSave("slot1");
JavaScript Equivalents
Task maps standard JavaScript asynchronous syntax directly to C++ coroutine keywords:
| JavaScript | C++ |
| async function | [](...) -> js::Task<T> |
| return value; | co_return value; |
| throw new Error() | co_return js::Error::Make(...) |
| await promise | co_await js::Await<T>(promise) |
Awaiting Page Promises
Pass a call to a page function to Await() to invoke it and await its returned Promise:
co_return answer ? *answer : false;
};
A handle to a live JavaScript value.
Definition Value.h:210
auto Await(const Value &promise)
Wait for a JavaScript promise from a Task:
Definition Task.h:298
Expected< T, Error > Result
The result of a JavaScript operation that can fail: a T or a js::Error.
Definition Error.h:520
The returned Result holds the resolved value converted to the requested type, or an Error holding the rejection reason, a type conversion failure, or a page-gone error if the page navigates away first.
Threads and Timing
Coroutines follow these execution and threading rules:
- The coroutine body runs on the Renderer's thread. It starts synchronously inside the page's call up to the first co_await, and resumes on the Renderer's thread after each await.
- Worker threads must not touch JavaScript. Use RunOnWorker() to run background operations on the worker pool, passing plain C++ data in and out without touching Value or Context.
- The Promise settles during a later Renderer::Update(). Completions arrive on the Renderer's thread when your frame loop updates the renderer.
- Parameters stay valid for the entire Task. Arguments, references, and views like std::string_view and std::span remain valid across every co_await until the task completes.
Page Navigation and API Teardown
Waiting tasks handle navigation and destruction safely:
- A navigating page lets waiting tasks resume. Awaiting a Promise from that page yields a page-gone error, operations on its values fail safely, and the library discards the task's final result when it completes.
- Destroying the API cancels waiting tasks. Once the last owning handle to the API is destroyed, waiting tasks don't resume after their next co_await, and their Promises reject with a TypeError whose code is "ULJS_DETACHED".
- Note
- A Task<void> can't co_return an error. Return Task<bool> instead or use a Resolver to report failures from a void operation.
- See also
- Resolver, RunOnWorker(), Await()