# Qt Concurrent
QtPromise integrates with QtConcurrent to simplify chaining QFuture with QPromise.
# Convert
Converting QFuture<T>
to QPromise<T>
is done using the QtPromise::resolve
helper:
QFuture<int> future = QtConcurrent::run([]() {
// {...}
return 42;
});
QPromise<int> promise = QtPromise::resolve(future);
or simply:
auto promise = QtPromise::resolve(QtConcurrent::run([]() {
// {...}
}));
# Chain
Returning a QFuture<T>
in then
or fail
automatically
translate to QPromise<T>
:
QPromise<int> input = ...
auto output = input.then([](int res) {
return QtConcurrent::run([]() {
// {...}
return QString{"42"};
});
});
// output type: QPromise<QString>
output.then([](const QString& res) {
// {...}
});
The output
promise is resolved when the QFuture
is finished.
# Error
Exceptions thrown from a QtConcurrent thread reject the associated promise with the exception as the
reason. For this to work, the exception should be a QException
or its subclass. Correct subclassing of QException
includes overriding its methods clone()
and
raise()
. Without these overrides the promise will
be rejected with QException
.
Note that if you throw an exception that is not a subclass of QException
, the promise will
be rejected with QUnhandledException
(this restriction only applies to exceptions thrown from a QtConcurrent thread,
read more).
class CustomException : public QException
{
public:
void raise() const override { throw *this; }
CustomException* clone() const override { return new CustomException{*this}; }
};
// {...}
QPromise<int> promise = ...
promise.then([](int res) {
return QtConcurrent::run([]() {
// {...}
if (!success) {
throw CustomException{};
}
return QString{"42"};
});
}).fail([](const CustomException& error) {
// {...}
});