That is the first article of the series of “AsyncFuture Cookbook”. That is a collection of example code to cover a different kind of use-case with using AsyncFuture. If you have any suggestion and question, please feel free to leave a comment at the bottom of the article.
The Problem
In some scenario of concurrent processing, it may need a preprocessing function to determine the data to be passed to QtConcurrent::mapped. For example, you are asked to search for files in a directory recursively, then read them by a concurrent function.
This usage pattern is not supported by QtConurrent directly. You may need to break down the process into two steps, which is a bit troublesome.
An ideal solution is to call QtConcurrent::mapped within the run function directly like the code above. But the return type isQFuture<QFuture<T>>.
In order to listen for the result, it will need 2 nested QFutureWatcher objects. It is quite an inconvenience for a programmer.
The Solution
It is going to show you how to represent the result of the whole process by a using a single QFuture<T>
object instead of a QFuture<QFuture<T>>
. It is not returning the result of QtConcurrent::mapped, instead it will return a mirror object where the status like progressValue
and result value will be kept in sync.
The example code searches all the JSON files within a directory in a thread then read then by a concurrent function.
Prerequisite: The code below requires AsyncFuture 0.4.0.1 or above to run.
Method 1 — Deferred object + mutable lambda function
Method 2 — Deferred::complete(QFuture<QFuture<T>>)
Method 3 — observe(QFuture<QFuture<T>>)
Since AsyncFuture v0.4, the AsyncFuture::observe()
works with QFuture<QFuture<T>>
input. It will convert to Observable<T>.
So that it is not necessary to use nested QFutureWatcher to listen for the result.