# 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) {
    // {...}
});