Skip to content

QCoro::LazyTask

ModuleCoro
Include
#include <QCoroLazyTask>
CMake
target_link_libraries(myapp QCoro::Coro)
QMake
QT += QCoroCoro
Since0.11
template<typename T> class QCoro::LazyTask

QCoro::LazyTask<T> represents, as the name suggests, a lazily evaluated coroutine. A lazily evaluated coroutine is suspended immediately when called and will not execute its body until the returned QCoro::LazyTask<T> is co_awaited.

This is in contrast to QCoro::Task<T>, which is an eager coroutine, meaning that its body is executed immediately when invoked and is only suspended when it first co_awaits another coroutine.

Don't use LazyTask as a Qt slot

Do not use LazyTask<T> as a return type of Qt slots, or any other coroutine that can be invoked by the Qt event loop. The Qt event loop is not aware of coroutines and will never co_await the returned LazyTask<T>. Therefore, the coroutine's body would never be executed!

This is the main reason why the "default" QCoro::Task<T> coroutines are eager - they don't need to be co_awaited in order to be executed, which makes them compatible with the Qt event loop.

If you need to have a lazy coroutine that is also invokable from the Qt event loop, use an eager wrapper coroutine to pass to the event loop:

QCoro::LazyTask<> myLazyCoroutine();

Q_INVOKABLE QCoro::Task<> myLazyCoroutineWrapper() {
    co_await myLazyCoroutine();
}

The eager wrapper is always immediately executed, and since it will immediately start co_awaiting on the lazy coroutine, the lazy coroutine will effectively get executed immediately.

then() continuation

It is possible to chain a continuation to the coroutine by using .then(). It is possible to use both lazy and eager continuations and even non-coroutine continuations:

auto task = myLazyTask().then([]() -> QCoro::Task<> { ... });        // #1
auto task = myLazyTask().then([]() -> QCoro::LazyTask<> { ... });    // #2
auto task = myLazyTask().then([]() { return 42; })                   // #3

In case #1, the myLazyTask() will be evaluated eagerly becaues of the .then() continuation being eager (basically equivalent to the eager wrapper mentioned in the warning note at the top).

In case #2 and #3, the the entire chain will be evaluated lazily - that is, both the myLazyTask() and the .then() continuation will be evaluated only once task is co_awaited.

Blocking wait

It's possible to use QCoro::waitFor() to synchronously wait for completion of a lazy coroutine. Check the documentation in QCoro::Task<T> for details.

Interfacing with synchronous functions

See QCoro::connect() documentation forQCoro::Task` for details.