我看到 Qt 具有直接模拟boost::future的未来类,但是boost::promise的 qt 是什么?
5 回答
如接受的答案所示构建我自己的 QFuture 对我不起作用。起初它似乎在工作,但在我的测试中,我意识到它并没有阻止调用者。哎呀!因此,我进一步深入研究了代码,发现 QFutureInterface 是您想要用作“承诺”的东西。与 boost::promise 一样,QFutureInterface 是您在工作线程中与之交互的对象,它是 QFutures 的工厂。
所以这就是我在 Qt 4.8 中所做的(不确定这是否适用于更高版本)。
QFutureInterface<QVariant> promise;
promise.reportStarted();
...
promise.reportResult(someVariant);
promise.reportFinished();
然后在客户端线程中,假设您可以访问 QFutureInterface 'promise'
QVariant result = promise.future().result();
该future()
调用是用于创建绑定到 QFutureInterface 的 QFuture 的工厂方法。如果需要,您应该能够获得 QFuture 并result()
稍后调用它。
boost::promises 是在期货中设置值的方法。在 Qt 中,你不能设置期货,你只能返回它们。这是未来“设置”数据的唯一方法。
所以,为了设置未来的数据,你必须从一个被调用的函数中返回它QtConcurrent::run
。为此,您将使用 Qt 的任何机制在线程之间进行通信——事件、互斥保护变量等。您必须告诉运行将返回未来的代码的线程,将返回给定的未来。这是实现承诺的唯一方法。
唉,如果您想进入无证领域,那么以下代码boost::promise::setValue
将执行以下操作:
QFuture<int> f;
int i = 1;
...
f.d.reportResult(&i);
// or
f.d.reportFinished(&i);
我还没有费心检查它是否有效(还)。
没有官方的 Qt 模拟,但有一些社区库实现了 Promise(或类似模式):
- Ben Lau 的 AsyncFuture ( benlau/asyncfuture )
基于其他答案之一中QFutureInterface
提到的未记录内容。 它不完全是一个承诺模式,而是一个观察者模式。 - Benoit Walter 的 QtPromise ( bwalter/qt-promise )
部分基于 Ben Lau 的 AsyncFuture。 - 西蒙布鲁内尔的 QtPromise ( simonbrunel/qtpromise )
- 我的 QtPromise ( julrich/QtPromise )
免责声明:我是作者。
Qt 的 Promise 现在也可以通过 QML/JavaScript 获得:https ://v-play.net/updates/release-2-18-1-javascript-promises-for-rest-services-tinder-swipe-material-cards -qml-qsortfilterproxymodel-qml-youtube-player
这是一些示例代码:
import VPlayApps 1.0
import QtQuick 2.0
App {
Component.onCompleted: {
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = HttpRequest
.get("http://httpbin.org/get")
.then(function(resp) {
return resp.body;
});
var p4 = Promise.all([p1, p2, p3]);
p4.then(function(values) {
console.log(values[0]); // 3
console.log(values[1]); // 1337
console.log(values[2]); // resp.body
});
}
}
我创建了这个与 Qt 高度集成并实现类似 javascript 的承诺的库:
https://github.com/juangburgos/QDeferred
它允许创建一个线程安全的异步 API,如下所示:
multiplyNumbersInThread(3, 4)
.fail([](int res) {
Q_UNUSED(res);
qDebug() << "multiplyPositiveNumbers failed!";
})
.done([](int res) {
qDebug() << "multiplyPositiveNumbers succeded! Result :" << res;
});
希望你觉得它有用。