summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp27
-rw-r--r--src/corelib/thread/qfuture.qdoc34
2 files changed, 55 insertions, 6 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp b/src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp
index dfa9b670e7..4fe3f7e99e 100644
--- a/src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp
@@ -72,3 +72,30 @@ i.toBack();
while (i.hasPrevious())
qDebug() << i.previous();
//! [2]
+
+//! [3]
+using NetworkReply = std::variant<QByteArray, QNetworkReply::NetworkError>;
+
+enum class IOError { FailedToRead, FailedToWrite };
+using IOResult = std::variant<QString, IOError>;
+//! [3]
+
+//! [4]
+QFuture<IOResult> future = QtConcurrent::run([url] {
+ ...
+ return NetworkReply(QNetworkReply::TimeoutError);
+}).then([](NetworkReply reply) {
+ if (auto error = std::get_if<QNetworkReply::NetworkError>(&reply))
+ return IOResult(IOError::FailedToRead);
+
+ auto data = std::get_if<QByteArray>(&reply);
+ // try to write *data and return IOError::FailedToWrite on failure
+ ...
+});
+
+auto result = future.result();
+if (auto filePath = std::get_if<QString>(&result)) {
+ // do something with *filePath
+else
+ // process the error
+//! [4]
diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc
index 8b354fe114..fc2892ad2d 100644
--- a/src/corelib/thread/qfuture.qdoc
+++ b/src/corelib/thread/qfuture.qdoc
@@ -51,9 +51,31 @@
QFuture provides a \l{Java-style iterators}{Java-style iterator}
(QFutureIterator) and an \l{STL-style iterators}{STL-style iterator}
- (QFuture::const_iterator). Using these iterators is another way to access
+ (QFuture::const_iterator). Using these iterators is another way to access
results in the future.
+ If the result of one asynchronous computation needs to be passed
+ to another, QFuture provides a convenient way of chaining multiple
+ sequential computations using then(). Additionally, onFailed() can be used
+ to handle any failures that occurred in the chain. Note that QFuture relies
+ on exceptions for the error handling. If using exceptions is not an option,
+ you can still indicate the error state of QFuture, by making the error type
+ part of the QFuture type. For example, you can use std::variant, std::any or
+ similar for keeping the result or failure or make your custom type.
+
+ The example below demonstrates how the error handling can be done without
+ using exceptions. Let's say we want to send a network request to obtain a large
+ file from a network location. Then we want to write it to the file system and
+ return its location in case of a success. Both of these operations may fail
+ with different errors. So, we use std::variant to keep the result
+ or error:
+
+ \snippet code/src_corelib_thread_qfuture.cpp 3
+
+ And we combine the two operations using then():
+
+ \snippet code/src_corelib_thread_qfuture.cpp 4
+
QFuture also offers ways to interact with a runnning computation. For
instance, the computation can be canceled with the cancel() function. To
pause the computation, use the setPaused() function or one of the pause(),
@@ -347,7 +369,7 @@
\sa takeResult(), result(), resultAt(), results(), resultCount(), isValid()
*/
-/* \fn template <typename T> std::vector<T> QFuture<T>::takeResult()
+/*! \fn template <typename T> std::vector<T> QFuture<T>::takeResult()
Call this function only if isValid() returns \c true, otherwise
the behavior is undefined. This function takes the first result from
@@ -369,12 +391,12 @@
\sa takeResults(), result(), results(), resultAt(), isValid()
*/
-/* \fn template <typename T> std::vector<T> QFuture<T>::isValid() const
+/*! \fn template <typename T> bool QFuture<T>::isValid() const
- Returns true if a result or results can be accessed or taken from this
- QFuture object. Returns false after the result was taken from the future.
+ Returns \c true if a result or results can be accessed or taken from this
+ QFuture object. Returns false after the result was taken from the future.
- \sa takeResults(), takeResult(), result(), results(), resultAt()
+ \sa takeResults(), takeResult(), result(), results(), resultAt()
*/
/*! \fn template <typename T> QFuture<T>::const_iterator QFuture<T>::begin() const