QIfPendingReply 类
template <typename T> class QIfPendingReply提供异步结果的模板类。 更多...
头文件 | #include <QIfPendingReply> |
qmake | QT += interfaceframework |
实例化自 | PendingReply |
继承自 | QIfPendingReplyBase |
公共函数
QIfPendingReply(const T &value) | |
T | reply() const |
void | setSuccess(const T &val) |
void | then(const std::function<void (const T &)> &success, const std::function<void ()> &failed = std::function<void()>()) |
静态公共成员
QIfPendingReply<T> | createFailedReply() |
相关非成员
typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, void>::type | qIfRegisterPendingReplyType(const char *name = nullptr) |
void | qifRegisterPendingReplyBasicTypes() |
详细描述
QIfPendingReply 是一个提供异步结果的模板类。它可以作为异步函数的返回值,类似于 QFuture。
与 QFuture 不同,QIfPendingReply also works in QML,并且特别为此设计。存储在 QIfPendingReply 中的数据在所有回复对象的副本之间隐式共享,这有助于保持内存和性能的低占用。
QML API 非常类似于 JavaScript Promises,同时 C++ API 提供了对 Qt 的信号和槽的支持。
QIfPendingReply 提持特定类型的结果。类型需要有默认构造函数和复制构造函数。默认情况下,支持大多数最基本 Qt 类型。可以通过使用 qIfRegisterPendingReplyType 函数添加新类型。
创建 QIfPendingReply 时,它还没有设置有效的结果。这可以通过 resultAvailable 属性来检查。可以使用 setFailed 或 setSuccess 函数设置回复的结果。使用此函数设置结果只能进行一次,并且以后不能更改。可以通过 success 属性确定 QIfPendingReply 是否成功。
编写返回 QIfPendingReply 的函数
在编写返回QIfPendingReply的函数时,通常需要在实际操作之前进行一些输入验证并返回。如果不使用QIfPendingReply,则函数可能会写得更像这样
QString displayName(const QUuid &id) { if (id.isNull) return QString(); //do something and wait until the result is ready (synchronous) asyncAPI.getDisplayName(id); asyncAPI.waitForFinished(&displayNameChanged); return asyncAPI.displayName(); }
此函数使用异步API,例如由IPC提供的API。getDisplayName(id)开始任务,一旦结果准备就绪,则会发出displayNameChanged信号,实际的值可以通过displayName()函数读取。提供的函数使用waitForFinished()方法实际等待信号的发出,返回值并使此API同步。
将此代码移至使用QIfPendingReply时,验证检查需要修复以返回有效的QIfPendingReply。为了更方便地返回失败的回复,可以使用QIfPendingReply::createFailedReply()函数。
完全异步重写上述函数使用QIfPendingReply将类似于以下内容
QIfPendingReply<QString> displayName(const QUuid &id) { if (id.isNull) return QIfPendingReply<QString>::createFailedReply(); QIfPendingReply<QString> reply //connect to the change signal and set the result to the async reply when ready connect(asyncAPI, &displayNameChanged, this, [reply, asyncAPI]() mutable { reply.setSuccess(asyncAPI.displayName()); }); //start getting the name asyncAPI.getDisplayName(id); return reply; }
现在立即创建一个新的QIfPendingReply并传递给connect语句中使用的lambda。实际任务随后启动,并返回回复对象。一旦异步API发出displayNameChanged信号,lambda将被执行,QIfPendingReply将被标记为成功,并将其值设置为displayName()。
注意:所有QIfPendingReply的副本都使用隐式共享。当所有待处理的回复副本被删除时,此数据将释放。
使用返回QIfPendingReply的函数
在使用返回QIfPendingReply的函数时,首先应检查是否已可用结果使用isResultAvailable属性,并按相应执行。之后,您可以开始连接由QIfPendingReplyWatcher提供的信号。
信号和槽
为了保持内存占用低,QIfPendingReply不直接提供信号,因为它不需要从QObject继承,而使用Q_GADGET宏。要在一旦结果准备就绪时通知,可以使用QIfPendingReplyWatcher。可以使用watcher属性检索监视器。
以下是一个关于如何使用上述API的示例
QUuid uuid = createUuid(); QIfPendingReply<QString> reply = displayName(uuid); if (reply.isResultAvailable()) { if (reply.isSuccessfull()) useDisplayName(reply.value()); else qWarning("getting the displayName failed"); } else { connect(reply.watcher(), &QIfPendingReplyWatcher::valueChanged, this, [this, reply]() { if (reply.isSuccessfull()) useDisplayName(reply.value()); else qWarning("getting the displayName failed"); }); }
如上所述,首先检查待处理的回复是否已有结果,如果没有,则使用监视器的信号来响应valueChanged信号。
注意:返回的QIfPendingReplyWatcher属于QIfPendingReply及其所有副本。如果所有QIfPendingReply的副本都被删除,则其QIfPendingReplyWatcher也会被删除。
有关在QML中的使用,请参阅QML文档。
成员函数文档
QIfPendingReply::QIfPendingReply(const T &value)
创建一个新的QIfPendingReply,用于存储类型T。使用value将待处理的回复设置为成功。
此操作等同于
QIfPendingReply<T> reply. reply.setSuccess(value);
[静态]
QIfPendingReply<T> QIfPendingReply::createFailedReply()
创建一个标记为失败的回复对象。在函数返回回复的错误情况中,这是一个方便的操作。
QIfPendingReply<QString> doSomething(int value) { if (value <= 0) { qWarning("The value needs to be bigger than 0"); return QIfPendingReply<QString>::createFailedReply() } QIfPendingReply<QString> reply; ... return reply; }
T QIfPendingReply::reply() const
返回回复的结果。如果没有设置结果或当回复标记为失败时,返回一个默认构造的值。
另请参阅 setSuccess 和 setFailed.
void QIfPendingReply::setSuccess(const T &val)
将回复的结果设置为 val 并将该回复标记为成功。
注意: 结果只能设置一次,并且以后无法更改。
另请参阅 setFailed.
void QIfPendingReply::then(const std::function<void (const T &)> &success, const std::function<void ()> &failed = std::function<void()>())
设置在结果交付时调用的 C++ 回调。如果回复成功 success 被调用;否则 failed 被调用。
success 回调接收回复值作为参数。
如果在调用此函数时挂起的回复结果已经可用,则相应的回调函数将立即运行。
相关非成员
template <typename T> typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, void>::type qIfRegisterPendingReplyType(const char *name = nullptr)
将类型名 name 记录在用于 QIfPendingReply 的类型 T
。任何具有公共默认构造函数、公共拷贝构造函数和公共析构函数的类或结构体都可以注册。
此函数要求在函数调用时 T
是一个完全定义的类型。对于指针类型,还要求指向的类型是完全定义的。使用 Q_DECLARE_OPAQUE_POINTER() 能够注册前向声明的类型的指针。
请参阅 qRegisterMetaType 获取更多信息。
void qifRegisterPendingReplyBasicTypes()
将所有 Qt 基本类型的 QIfPendingReply 注册到元类型系统中。
通常在创建 QCoreApplication 或 QIfPendingReply 时自动调用此函数,无需手动调用。
© 2024 Qt 公司有限公司。此处包含的文档贡献是各自拥有者的版权。此处提供的文档根据自由软件基金会发布的 GNU自由文档许可协议版本1.3 的条款许可。Qt 及其LOGO是芬兰及/或其他国家的 The Qt Company Ltd. 的商标。所有其他商标均为各自拥有者的财产。