Differential D18758 Diff 58398 kdevplatform/3rdparty/qtpromise/qtpromise-0.5.0/docs/qtpromise/getting-started.md
Changeset View
Changeset View
Standalone View
Standalone View
kdevplatform/3rdparty/qtpromise/qtpromise-0.5.0/docs/qtpromise/getting-started.md
- This file was added.
1 | # Getting Started | ||||
---|---|---|---|---|---|
2 | | ||||
3 | ## Installation | ||||
4 | | ||||
5 | QtPromise is a [header-only](https://en.wikipedia.org/wiki/Header-only) library, simply download the [latest release](https://github.com/simonbrunel/qtpromise/releases/latest) (or [`git submodule`](https://git-scm.com/docs/git-submodule)) and include `qtpromise.pri` from your project `.pro`. | ||||
6 | | ||||
7 | ### qpm | ||||
8 | | ||||
9 | Alternatively and **only** if your project relies on [qpm](https://www.qpm.io/), you can install QtPromise as follow: | ||||
10 | | ||||
11 | ```bash | ||||
12 | qpm install com.github.simonbrunel.qtpromise | ||||
13 | ``` | ||||
14 | | ||||
15 | ## Usage | ||||
16 | | ||||
17 | The recommended way to use QtPromise is to include the single module header: | ||||
18 | | ||||
19 | ```cpp | ||||
20 | #include <QtPromise> | ||||
21 | ``` | ||||
22 | | ||||
23 | ## Example | ||||
24 | | ||||
25 | Let's first make the code more readable by using the library namespace: | ||||
26 | | ||||
27 | ```cpp | ||||
28 | using namespace QtPromise; | ||||
29 | ``` | ||||
30 | | ||||
31 | This `download` function creates a [promise from callbacks](qpromise/constructor.md) which will be resolved when the network request is finished: | ||||
32 | | ||||
33 | ```cpp | ||||
34 | QPromise<QByteArray> download(const QUrl& url) | ||||
35 | { | ||||
36 | return QPromise<QByteArray>([&]( | ||||
37 | const QPromiseResolve<QByteArray>& resolve, | ||||
38 | const QPromiseReject<QByteArray>& reject) { | ||||
39 | | ||||
40 | QNetworkReply* reply = manager->get(QNetworkRequest(url)); | ||||
41 | QObject::connect(reply, &QNetworkReply::finished, [=]() { | ||||
42 | if (reply->error() == QNetworkReply::NoError) { | ||||
43 | resolve(reply->readAll()); | ||||
44 | } else { | ||||
45 | reject(reply->error()); | ||||
46 | } | ||||
47 | | ||||
48 | reply->deleteLater(); | ||||
49 | }); | ||||
50 | }); | ||||
51 | } | ||||
52 | ``` | ||||
53 | | ||||
54 | The following method `uncompress` data in a separate thread and returns a [promise from QFuture](qtconcurrent.md): | ||||
55 | | ||||
56 | ```cpp | ||||
57 | QPromise<Entries> uncompress(const QByteArray& data) | ||||
58 | { | ||||
59 | return QtPromise::resolve(QtConcurrent::run([](const QByteArray& data) { | ||||
60 | Entries entries; | ||||
61 | | ||||
62 | // {...} uncompress data and parse content. | ||||
63 | | ||||
64 | if (error) { | ||||
65 | throw MalformedException(); | ||||
66 | } | ||||
67 | | ||||
68 | return entries; | ||||
69 | }, data)); | ||||
70 | } | ||||
71 | ``` | ||||
72 | | ||||
73 | It's then easy to chain the whole asynchronous process using promises: | ||||
74 | - initiate the promise chain by downloading a specific URL, | ||||
75 | - [`then`](qpromise/then.md) *and only if download succeeded*, uncompress received data, | ||||
76 | - [`then`](qpromise/then.md) validate and process the uncompressed entries, | ||||
77 | - [`finally`](qpromise/finally.md) perform operations whatever the process succeeded or failed, | ||||
78 | - and handle specific errors using [`fail`](qpromise/fail.md). | ||||
79 | | ||||
80 | ```cpp | ||||
81 | download(url).then(&uncompress).then([](const Entries& entries) { | ||||
82 | if (entries.isEmpty()) { | ||||
83 | throw UpdateException("No entries"); | ||||
84 | } | ||||
85 | // {...} process entries | ||||
86 | }).finally([]() { | ||||
87 | // {...} cleanup | ||||
88 | }).fail([](QNetworkReply::NetworkError err) { | ||||
89 | // {...} handle network error | ||||
90 | }).fail([](const UpdateException& err) { | ||||
91 | // {...} handle update error | ||||
92 | }).fail([]() { | ||||
93 | // {...} catch all | ||||
94 | }); | ||||
95 | ``` |