QTBUG-101025 asks how a QFuture returned from C++ should be usable in QML.
It dates back to 2022. I posted an exploratory patch last year, and after
the review feedback on Jira and Gerrit I've now reworked it. Before the API
settles, I'd like to hear from people who build or consume asynchronous C++
APIs in QML.

The motivation: in the commercial Qt projects I've worked on, more and more
asynchronous APIs cross the C++/QML boundary. Usually a Q_INVOKABLE starts
work through QtConcurrent, a QPromise or a worker thread, and the result
comes back through a signal or a property. Other teams build their own
bridges to JavaScript Promises. Both need glue for every API, and with
overlapping calls it's awkward to match a result to the request that
produced it.

With the patches, this works:

    service.fetchPerson(id)
        .then(person => nameLabel.text = person.name)
        .catch(error => errorLabel.text = error.message)

- A QFuture<T> returned to QML becomes a small thenable object that still
holds the original future. Passing it back to C++ gives the same future.
- then() and catch() return plain JavaScript Promises, so chaining,
Promise.all() and returning promises or futures from handlers work as usual.
- The promise fulfills with the future's first result, like
QFuture::result(), or with undefined for QFuture<void>. Cancellation and
exceptions reject it with an Error.
- Nothing needs to be registered. It works for the result types QML already
understands: built-ins, QObject pointers, value types, enums, and lists of
those.
- qmllint knows about then() and catch() on futures.

Deliberately not there yet: typed properties (property future<T>), progress
and multiple results, and the reverse direction, passing a JavaScript
Promise to a C++ QFuture<QVariant>. The reverse direction would be my next
step.

What I'd like to know:

1. Does a thenable with Promise continuations fit how you'd use it? Or do
you need more of QFuture in QML, such as cancel(), progress, or a "running"
state for a busy indicator?
2. Is "first result, or undefined if there is none" the right default?
3. Should cancellation be distinguishable from a failure, for example by a
separate error name?
4. Would you pass JavaScript Promises to C++ as QFutures, and what for?

Short examples of how your code handles this today would help a lot.

Ticket: https://qt-project.atlassian.net/browse/QTBUG-101025
Patches: https://codereview.qt-project.org/q/topic:qtbug-101025
(qtbase 775917; qtdeclarative 692993, with docs in 775924 and qmllint
support in 775925)

Thanks,
Przemek
-- 
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to