QIviPendingReply 类
template <typename T> class QIviPendingReply提供异步结果的模板类。 更多...
头文件 | #include <QIviPendingReply> |
qmake | QT += ivicore |
实例化 | PendingReply |
继承 | QIviPendingReplyBase |
公共函数
QIviPendingReply(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()>()) |
静态公共成员
QIviPendingReply<T> | createFailedReply() |
相关非成员
void | qIviRegisterPendingReplyType(const char *name = nullptr) |
void | qiviRegisterPendingReplyBasicTypes() |
详细描述
QIviPendingReply 是一个提供异步结果的模板类。它可以作为异步函数的返回值使用,类似于 QFuture。
与 QFuture 相比,QIviPendingReply 也可以在 QML 中工作,并且特别为此目的而制作。存储在 QIviPendingReply 中的数据在所有副本之间隐式共享。这有助于降低内存和性能开销。
QML API 与 JavaScript Promises 非常相似,同时 C++ API 也提供了对 Qt 信号和槽的支持。
QIviPendingReply 持有特定类型的结果。该类型需要具有默认构造函数和复制构造函数。默认情况下,支持大多数 Qt 基本类型。通过使用 qIviRegisterPendingReplyType 函数可以添加新的类型。
当 QIviPendingReply 创建时,它还没有设置有效结果。这可以通过使用 resultAvailable 属性来检查。可以通过使用 setFailed 或 setSuccess 函数设置回复的结果。使用此函数设置结果只能进行一次,以后不能更改。可以通过 success 属性确定 QIviPendingReply 是否已成功。
编写返回 QIviPendingReply 的函数
编写返回 QIviPendingReply 的函数时,通常需要在实际操作之前执行一些输入验证并返回。不使用 QIviPendingReply,可以编写函数如下:
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变为同步。
当将此代码迁移到使用QIviPendingReply时,需要修复验证检查以返回有效的QIviPendingReply。为了更方便地返回失败的回复,可使用QIviPendingReply::createFailedReply()函数。
将上述函数完全异步重写为使用QIviPendingReply,如下所示:
QIviPendingReply<QString> displayName(const QUuid &id) { if (id.isNull) return QIviPendingReply<QString>::createFailedReply(); QIviPendingReply<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; }
现在立即创建一个新的QIviPendingReply并将其传递到连接声明中使用的lambda函数。实际的任务稍后开始,并且返回响应对象。一旦异步API发出displayNameChanged信号,lambda函数就会被执行,QIviPendingReply被标记为成功,并将值设置到displayName()。
注意:所有QIviPendingReply的副本都使用隐式共享。一旦所有待处理回复的副本被删除,该数据就会被释放。
使用返回QIviPendingReply的函数
当使用返回QIviPendingReply的函数时,首先要检查是否已经可用结果,使用isResultAvailable属性,并相应行动。之后,您可以对QIviPendingReplyWatcher提供的信号进行连接。
信号和槽
为了保持内存足迹低,QIviPendingReply不直接提供信号,因为它不需要从QObject派生,而是使用Q_GADGET宏。要在一旦有结果准备好的时候被告知,可以使用QIviPendingReplyWatcher。可以使用监视器属性检索监视器。
以下是一个使用上述API的示例:
QUuid uuid = createUuid(); QIviPendingReply<QString> reply = displayName(uuid); if (reply.isResultAvailable()) { if (reply.isSuccessfull()) useDisplayName(reply.value()); else qWarning("getting the displayName failed"); } else { connect(reply.watcher(), &QIviPendingReplyWatcher::valueChanged, this, [this, reply]() { if (reply.isSuccessfull()) useDisplayName(reply.value()); else qWarning("getting the displayName failed"); }); }
如上所述,首先检查待处理的回复是否已有结果准备就绪,如果没有,则使用监视器的信号来响应valueChanged信号。
注意:返回的QIviPendingReplyWatcher属于QIviPendingReply及其所有副本。如果所有QIviPendingReply的副本都被删除,其QIviPendingReplyWatcher也会被删除。
有关在QML中的使用,请参阅QML文档。
成员函数文档
QIviPendingReply::QIviPendingReply(const T &value)
创建一个新的QIviPendingReply,存储类型T。使用value将待处理的回复设置为成功。
这等价于
QIviPendingReply<T> reply. reply.setSuccess(value);
[静态]
QIviPendingReply<T> QIviPendingReply::createFailedReply()
创建一个标记为失败的回复对象。这在函数返回回复的错误情况下很有用。
QIviPendingReply<QString> doSomething(int value) { if (value <= 0) { qWarning("The value needs to be bigger than 0"); return QIviPendingReply<QString>::createFailedReply() } QIviPendingReply<QString> reply; ... return reply; }
T QIviPendingReply::reply() const
返回回复的结果。如果没有设置结果或者回复被标记为失败,将返回默认构造的值。
另请参阅:setSuccess和setFailed。
void QIviPendingReply::setSuccess(const T &val)
将回复的结果设置为val,并将回复标记为成功。
注意:结果只能设置一次,之后无法再次更改。
另请参阅:setFailed.
void QIviPendingReply::then(const std::function<void (const T &)> &success, const std::function<void ()> &failed = std::function<void()>())
设置结果传递时一次调用的C++回调函数。如果回复成功,则调用success;否则,调用failed。
success回调函数将接收回复值作为参数。
如果在此函数被调用时,待处理回复的结果已经可用,则立即运行相应的回调函数。
相关非成员
template <typename T> void qIviRegisterPendingReplyType(const char *name = nullptr)
注册类型名称name以在QIviPendingReply内部使用类型T
。任何具有公共默认构造函数、公共拷贝构造函数和公共析构函数的类或结构都可以注册。
此函数要求T
是调用该函数时的完全定义的类型。对于指针类型,它还要求指针指向的类型是完全定义的。使用Q_DECLARE_OPAQUE_POINTER()可以注册指向已经声明的类型的指针。
有关更多信息,请参阅qRegisterMetaType.
void qiviRegisterPendingReplyBasicTypes()
将所有Qt基本类型的QIviPendingReply注册到元类型系统中。
通常,在创建QCoreApplication或QIviPendingReply时自动调用此函数,无需手动调用。
©2020 The Qt Company Ltd. 本文档中的文档贡献是各自所有者的版权。本文档是根据自由软件基金会发布的GNU自由文档许可证版本1.3的条款提供的。Qt及其相关标志是芬兰或全球其他国家的The Qt Company Ltd.的商标。所有其他商标均为其各自所有者的财产。