3
\$\begingroup\$

After using JavaScript for a while, I think callbacks are pretty good for asynchronous programming, but I haven't seen anything similar in C++. What I want to achieve is to start a worker thread from a function/lambda, and then use a callback to receive the result, which will be run in the main thread. The callback is required to run in the main thread because Qt GUI code is limited to run there. asyncRun is a convenient function to achieve the above. Let me know what you think.

template <typename AsyncFunc, typename Callback>
void asyncRun(QObject* obj, AsyncFunc asyncFunc, Callback callback) {
    auto asyncFuncWrapper = [=]() {
        auto result = asyncFunc();
        QTimer::singleShot(0, obj, std::bind(callback, result));
    };
    QtConcurrent::run(asyncFuncWrapper);
}

// Convenient function to run the callback in the main thread.
template <typename AsyncFunc, typename Callback>
void asyncRun(AsyncFunc asyncFunc, Callback callback) {
    asyncRun(QCoreApplication::instance(), asyncFunc, callback);
}

// Example usages
asyncRun([]() {
    qDebug() << "thread:" << QThread::currentThreadId();
    QThread::msleep(500);
    return 666;
}, [=](int result) {
    qDebug() << "thread:" << QThread::currentThreadId() << result;
});
\$\endgroup\$
  • \$\begingroup\$ We have Promises in C++ en.cppreference.com/w/cpp/thread/promise \$\endgroup\$ – Martin York Oct 13 '17 at 20:21
  • \$\begingroup\$ @LokiAstari I am aware of Promises in C++ but I am not familiar with it. My problem with it is it does not do .then() like the JavaScript version. With .then(), I can write the asyncFunc and the callback in the same place. Without .then(), I need to find another place in the code (maybe another function, or even another class) to put future.wait(). \$\endgroup\$ – Snowfish Oct 13 '17 at 22:13
1
\$\begingroup\$

This answer seems to be what you are looking for. I copy it here for reference:

There is this library that is highly integrated with Qt and implements javascript-like promises:

https://github.com/juangburgos/QDeferred

It allows to create a thread-safe async API as follows:

multiplyNumbersInThread(3, 4)
.fail([](int res) {
    Q_UNUSED(res);
    qDebug() << "multiplyPositiveNumbers failed!";
})
.done([](int res) {
    qDebug() << "multiplyPositiveNumbers succeded! Result :" << res;
});
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.