QtPromise - Promises/A+ for Qt/C++



  • I recently published a C++ implementation of promise that leverages Qt classes. It follows as far as possible the Promises/A+ specifications with an API mostly inspired by Bluebird and Q. QtPromise is a header-only library that only depends on QtCore (5.4+) with C++11 support enabled (read more).

    QtPromise consists of a main template class, QPromise<T> (T being the promise value type), providing the usual continuation methods such as then(), fail() and finally() (all of them being processed asynchronously). Errors are handled as exceptions and thus can be of any type. QtPromise also integrates with QFuture and is thread-safe. You can learn more about this project on GitHub (MIT licence). Feedback and contributions are welcome :)

    Example

    #include <QtPromise>
    using namespace QtPromise;
    

    This download function creates a promise from callbacks which will be resolved when the network request is finished:

    QPromise<QByteArray> download(const QUrl& url)
    {
        return QPromise<QByteArray>([&](
            const QPromiseResolve<QByteArray>& resolve,
            const QPromiseReject<QByteArray>& reject) {
    
            QNetworkReply* reply = manager->get(QNetworkRequest(url));
            QObject::connect(reply, &QNetworkReply::finished, [=]() {
                if (reply->error() == QNetworkReply::NoError) {
                    resolve(reply->readAll());
                } else {
                    reject(reply->error());
                }
                reply->deleteLater();
            });
        });
    }
    

    The following method uncompress data in a separate thread and returns a promise from QFuture:

    QPromise<Entries> uncompress(const QByteArray& data)
    {
        return qPromise(QtConcurrent::run([](const QByteArray& data) {
            Entries entries;
    
            // {...} uncompress data and parse content.
    
            if (error) {
                throw MalformedException();
            }
    
            return entries;
        }, data));
    }
    

    It's then easy to chain the whole asynchronous process using promises:

    • initiate the promise chain by downloading a specific URL,
    • then and only if download succeeded, uncompress received data,
    • then validate and process the uncompressed entries,
    • finally perform operations whatever the process succeeded or failed,
    • and handle specific errors using fail.
    download(url).then(&uncompress).then([](const Entries& entries) {
        if (entries.isEmpty()) {
            throw UpdateException("No entries");
        }
        // {...} process entries
    }).finally([]() {
        // {...} cleanup
    }).fail([](QNetworkReply::NetworkError err) {
        // {...} handle network error
    }).fail([](const UpdateException& err) {
        // {...} handle update error
    }).fail([]() {
        // {...} catch all
    });
    

  • Qt Champions 2016

    Hi,
    Thanks for that!
    Have also a look at @benlau's work here. Perhaps you could even exchange experience/ideas.



  • that's really helpful for me like as a beginner in this field. I also want to expert in c++


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.