Add an example of error handling of QFuture without using exceptions
Also fixed a few unrelated typos in docs. Task-number: QTBUG-83236 Change-Id: I776cda8f0ef4de6c4a93e94092dc19e94d1884c8 Reviewed-by: Vitaly Fanaskov <vitaly.fanaskov@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
This commit is contained in:
parent
300aaec2f9
commit
339dd743a9
@ -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]
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user