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;
});
1 Answer 1
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;
});
Explore related questions
See similar questions with these tags.
Promises
in C++ en.cppreference.com/w/cpp/thread/promise \$\endgroup\$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 theasyncFunc
and thecallback
in the same place. Without.then()
, I need to find another place in the code (maybe another function, or even another class) to putfuture.wait()
. \$\endgroup\$