# Qt Concurrent
QtPromise integrates with QtConcurrent (opens new window) 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 (opens new window).
# 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
(opens new window)
or its subclass. Correct subclassing of QException
(opens new window)
includes overriding its methods clone()
(opens new window) and
raise()
(opens new window). Without these overrides the promise will
be rejected with QException
(opens new window).
Note that if you throw an exception that is not a subclass of QException
, the promise will
be rejected with QUnhandledException
(opens new window)
(this restriction only applies to exceptions thrown from a QtConcurrent thread,
read more (opens new window)).
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) {
// {...}
});