mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 08:46:44 +08:00
207 lines
20 KiB
HTML
207 lines
20 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8" />
|
|
<title>Tutorial » Creating continuables | Continuable</title>
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
|
<link rel="stylesheet" href="m-dark+doxygen.compiled.css" />
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
|
<link rel="stylesheet" href="base.css" />
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
|
<link rel="stylesheet" href="terminal.css" />
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
|
<link rel="stylesheet" href="atom-one-dark.css" />
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="theme-color" content="#23373B" />
|
|
</head>
|
|
<body>
|
|
<header><nav id="navigation">
|
|
<div class="m-container">
|
|
<div class="m-row">
|
|
<a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">Continuable <span class="m-thin">4.1.0</span></a>
|
|
<div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
|
|
<a href="#search" class="m-dox-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
|
|
<path d="m6 0c-3.3144 0-6 2.6856-6 6 0 3.3144 2.6856 6 6 6 1.4858 0 2.8463-0.54083 3.8945-1.4355-0.0164 0.33797 0.14734 0.75854 0.5 1.1504l3.2227 3.7891c0.55185 0.6139 1.4517 0.66544 2.002 0.11524 0.55022-0.55022 0.49866-1.4501-0.11524-2.002l-3.7891-3.2246c-0.39184-0.35266-0.81242-0.51469-1.1504-0.5 0.89472-1.0482 1.4355-2.4088 1.4355-3.8945 0-3.3128-2.6856-5.998-6-5.998zm0 1.5625a4.4375 4.4375 0 0 1 4.4375 4.4375 4.4375 4.4375 0 0 1-4.4375 4.4375 4.4375 4.4375 0 0 1-4.4375-4.4375 4.4375 4.4375 0 0 1 4.4375-4.4375z"/>
|
|
</svg></a>
|
|
<a id="m-navbar-show" href="#navigation" title="Show navigation"></a>
|
|
<a id="m-navbar-hide" href="#" title="Hide navigation"></a>
|
|
</div>
|
|
<div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
|
|
<div class="m-row">
|
|
<ol class="m-col-t-6 m-col-m-none">
|
|
<li>
|
|
<a href="tutorial.html">Tutorial</a>
|
|
<ol>
|
|
<li><a href="tutorial-creating-continuables.html" id="m-navbar-current">Creating continuables</a></li>
|
|
<li><a href="tutorial-chaining-continuables.html">Chaining continuables</a></li>
|
|
<li><a href="tutorial-connecting-continuables.html">Connecting continuables</a></li>
|
|
<li><a href="tutorial-transforming-continuables.html">Transforming continuables</a></li>
|
|
<li><a href="tutorial-awaiting-continuables.html">Awaiting continuables</a></li>
|
|
<li><a href="tutorial-promisify-continuables.html">Promisify functions</a></li>
|
|
</ol>
|
|
</li>
|
|
<li>
|
|
<a href="pages.html">Pages</a>
|
|
<ol>
|
|
<li><a href="installation.html">Installation</a></li>
|
|
<li><a href="tutorial.html">Tutorial</a></li>
|
|
<li><a href="configuration.html">Configuration</a></li>
|
|
<li><a href="changelog.html">Changelog</a></li>
|
|
</ol>
|
|
</li>
|
|
<li>
|
|
<a href="modules.html">Modules</a>
|
|
<ol>
|
|
<li><a href="group___base.html">Base</a></li>
|
|
<li><a href="group___connections.html">Connections</a></li>
|
|
<li><a href="group___promisify.html">Promisify</a></li>
|
|
<li><a href="group___testing.html">Testing</a></li>
|
|
<li><a href="group___types.html">Types</a></li>
|
|
<li><a href="group___transforms.html">Transforms</a></li>
|
|
<li><a href="group___traversal.html">Traversal</a></li>
|
|
</ol>
|
|
</li>
|
|
</ol>
|
|
<ol class="m-col-t-6 m-col-m-none" start="4">
|
|
<li>
|
|
<a href="namespacecti.html">cti</a>
|
|
<ol>
|
|
<li><a href="namespacecti_1_1transforms.html">cti::transforms</a></li>
|
|
<li><a href="classcti_1_1continuable__base.html">cti::continuable_base</a></li>
|
|
<li><a href="classcti_1_1promise__base.html">cti::promise_base</a></li>
|
|
</ol>
|
|
</li>
|
|
<li class="m-show-m"><a href="#search" class="m-dox-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
|
|
<path d="m6 0c-3.3144 0-6 2.6856-6 6 0 3.3144 2.6856 6 6 6 1.4858 0 2.8463-0.54083 3.8945-1.4355-0.0164 0.33797 0.14734 0.75854 0.5 1.1504l3.2227 3.7891c0.55185 0.6139 1.4517 0.66544 2.002 0.11524 0.55022-0.55022 0.49866-1.4501-0.11524-2.002l-3.7891-3.2246c-0.39184-0.35266-0.81242-0.51469-1.1504-0.5 0.89472-1.0482 1.4355-2.4088 1.4355-3.8945 0-3.3128-2.6856-5.998-6-5.998zm0 1.5625a4.4375 4.4375 0 0 1 4.4375 4.4375 4.4375 4.4375 0 0 1-4.4375 4.4375 4.4375 4.4375 0 0 1-4.4375-4.4375 4.4375 4.4375 0 0 1 4.4375-4.4375z"/>
|
|
</svg> Search</a></li>
|
|
</ol>
|
|
<ol class="m-col-t-6 m-col-m-none">
|
|
<li>
|
|
<a href="https://github.com/Naios/continuable" aria-label="View source on Github"><i class="fa fa-github"></i> Code</a>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav></header>
|
|
<main><article>
|
|
<div class="m-container m-container-inflatable">
|
|
<div class="m-row">
|
|
<div class="m-col-l-10 m-push-l-1">
|
|
<h1>
|
|
<span class="m-breadcrumb"><a href="tutorial.html">Tutorial</a> »</span>
|
|
|
|
Creating continuables
|
|
</h1>
|
|
|
|
<p>Explains how to create a <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a>.</p>
|
|
<div class="m-block m-default">
|
|
<h3>Contents</h3>
|
|
<ul>
|
|
<li><a href="#tutorial-creating-continuables-ready">From a value or exception</a></li>
|
|
<li><a href="#tutorial-creating-continuables-promises">From a promise taking callable</a></li>
|
|
<li><a href="#tutorial-creating-continuables-invocation">The continuable invocation model</a></li>
|
|
</ul>
|
|
</div>
|
|
<p>A <a href="group___types.html#ga95d2328ba27fe194491b52073b58be50" class="m-dox">continuable</a> is an arbitrary instantiation of a <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a>, it represents the main class of the library and makes it possible to build up an asynchronous call hierarchy. When dealing with continuables we usually don't know its exact type for avoiding expensive type erasure.</p><p>The <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> is convertible to a <a href="group___types.html#ga95d2328ba27fe194491b52073b58be50" class="m-dox">continuable</a> which represents a specified type of the <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> on the cost of a type erasure.</p><section id="tutorial-creating-continuables-ready"><h2><a href="#tutorial-creating-continuables-ready">From a value or exception</a></h2><p>The library provides <a href="group___base.html#gaa1b6bcf17649b137e29c866ced3569c7" class="m-dox">make_<wbr />ready_<wbr />continuable</a> which may be used to create a <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> from an arbitrary amount of values:</p><pre class="m-code"><span class="k">auto</span> <span class="n">one</span> <span class="o">=</span> <span class="n">cti</span><span class="o">::</span><span class="n">make_ready_continuable</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
|
|
|
|
<span class="n">cti</span><span class="o">::</span><span class="n">continuable</span><span class="o"><</span><span class="kt">int</span><span class="p">,</span> <span class="kt">float</span><span class="p">,</span> <span class="kt">char</span><span class="o">></span> <span class="n">three</span> <span class="o">=</span>
|
|
<span class="n">cti</span><span class="o">::</span><span class="n">make_ready_continuable</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mf">1.f</span><span class="p">,</span> <span class="sc">'2'</span><span class="p">);</span></pre><aside class="m-note m-info"><h4>Note</h4><p>In most situations you will never use <a href="group___base.html#gaa1b6bcf17649b137e29c866ced3569c7" class="m-dox">make_<wbr />ready_<wbr />continuable</a> because the library is capable of working with plain values directly and thus this burdens unnecessary overhead.</p></aside><p>Additionally a <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> which resolves with an exception may be created through <a href="group___base.html#ga41794c321aef916f4fd0fe4c36aa9e6e" class="m-dox">make_<wbr />exceptional_<wbr />continuable</a>.</p><pre class="m-code"><span class="n">cti</span><span class="o">::</span><span class="n">continuable</span><span class="o"><</span><span class="kt">int</span><span class="o">></span> <span class="n">c</span> <span class="o">=</span> <span class="n">cti</span><span class="o">::</span><span class="n">make_exceptional_continuable</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">exception</span><span class="p">{});</span></pre></section><section id="tutorial-creating-continuables-promises"><h2><a href="#tutorial-creating-continuables-promises">From a promise taking callable</a></h2><p>The main function for creating a <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> is <a href="group___base.html#gaf47869ea139d88976af5b9654d6d61c0" class="m-dox">make_<wbr />continuable</a> which must be invoked with the types of arguments it resolves to. It accepts a callable object which accepts an arbitrary object (the <a href="classcti_1_1promise__base.html" class="m-dox">promise_<wbr />base</a>). The <a href="classcti_1_1promise__base.html" class="m-dox">promise_<wbr />base</a> is created by the library and then passed to the given callback. This is in contrast to the usage of the standard <code>std::promise</code> which is created by the user.</p><p>The <a href="classcti_1_1promise__base.html" class="m-dox">promise_<wbr />base</a> exposes methods to resolve it through result values or through an exception. Below we implement pseudo <code>http_request</code> function which resolves the request asynchronously trough a <code>std::string</code>.</p><pre class="m-code"><span class="k">auto</span> <span class="nf">http_request</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">url</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="n">cti</span><span class="o">::</span><span class="n">make_continuable</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="p">(</span>
|
|
<span class="p">[</span><span class="n">url</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">url</span><span class="p">)](</span><span class="k">auto</span><span class="o">&&</span> <span class="n">promise</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="c1">// Resolve the promise upon completion of the task.</span>
|
|
<span class="n">promise</span><span class="p">.</span><span class="n">set_value</span><span class="p">(</span><span class="s">"<html> ... </html>"</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Or promise.set_exception(...);</span>
|
|
<span class="p">});</span>
|
|
<span class="p">}</span></pre><p>An alternative would be a <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> with a result of zero arguments:</p><pre class="m-code"><span class="k">auto</span> <span class="nf">wait_for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">milliseconds</span> <span class="n">duration</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="n">cti</span><span class="o">::</span><span class="n">make_continuable</span><span class="o"><</span><span class="kt">void</span><span class="o">></span><span class="p">([](</span><span class="k">auto</span><span class="o">&&</span> <span class="n">promise</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="c1">// ^^^^</span>
|
|
|
|
<span class="c1">// Resolve the promise later when the duration is over</span>
|
|
<span class="n">promise</span><span class="p">.</span><span class="n">set_value</span><span class="p">();</span>
|
|
<span class="p">});</span></pre><p>A <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> may resolve with an arbitrary count of result values:</p><pre class="m-code"><span class="k">auto</span> <span class="nf">resolve_sth</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="n">cti</span><span class="o">::</span><span class="n">make_continuable</span><span class="o"><</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="p">,</span> <span class="kt">float</span><span class="p">,</span> <span class="kt">char</span><span class="o">></span><span class="p">(</span>
|
|
<span class="p">[](</span><span class="k">auto</span><span class="o">&&</span> <span class="n">promise</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="n">promise</span><span class="p">.</span><span class="n">set_value</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mf">2.f</span><span class="p">,</span> <span class="sc">'3'</span><span class="p">);</span>
|
|
<span class="p">});</span></pre><aside class="m-note m-danger"><h4>Warning</h4><p>A <a href="classcti_1_1promise__base.html" class="m-dox">promise_<wbr />base</a> is only usable once and thus invalidated after it was resolved!</p></aside><p>A <a href="classcti_1_1promise__base.html" class="m-dox">promise_<wbr />base</a> always exposes a call operator for resolving it as like when using <a href="classcti_1_1promise__base.html#a223d666944a70441b3837b461b1094c7" class="m-dox">promise_base::<wbr />set_value</a> or <a href="classcti_1_1promise__base.html#a449356e97645d44cf4194932cc2006d7" class="m-dox">promise_base::<wbr />set_exception</a>. See <a href="classcti_1_1promise__base.html" class="m-dox">promise_<wbr />base</a> for details.</p><aside class="m-note m-info"><h4>Note</h4><p>In order to make proper use of a <a href="classcti_1_1promise__base.html" class="m-dox">promise_<wbr />base</a> you should move it around, store it for later use and resolve it when the asynchronous task was finished or rejected.</p></aside></section><section id="tutorial-creating-continuables-invocation"><h2><a href="#tutorial-creating-continuables-invocation">The continuable invocation model</a></h2><p>An asynchronous call hierarchy that is stored inside the <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> is executed when its result is requested (lazy evaluation) in contrast to other commonly used implementations such as <code>std::future</code> which execute the asynchronous call hierarchy instantly on creation (eager evaluation).</p><p>The lazy evaluation strategy used by continuables has many benefits over eager evaluation that is used by other common implementations:</p><ul><li>prevention of side effects</li><li>evasion of race conditions</li><li>ensured deterministic behaviour.</li></ul><p>The asynchronous call hierarchy is started when the <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> is destructed or the <a href="classcti_1_1continuable__base.html#a26ca692e597ebd8beff7d58d8bf584f4" class="m-dox">continuable_base::<wbr />done</a> method is called. It is possible to disable the automatic start through calling <a href="classcti_1_1continuable__base.html#a3c8d7fefc2f65fcd474c99d821809d24" class="m-dox">continuable_base::<wbr />freeze</a> on the corresponding <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a>.</p><aside class="m-note m-warning"><h4>Attention</h4><p>A <a href="classcti_1_1continuable__base.html" class="m-dox">continuable_<wbr />base</a> is not designed to be stored permanently, make sure you call <a href="classcti_1_1continuable__base.html#a3c8d7fefc2f65fcd474c99d821809d24" class="m-dox">continuable_base::<wbr />freeze</a> before storing it and start the continuation chain later through calling <a href="classcti_1_1continuable__base.html#a26ca692e597ebd8beff7d58d8bf584f4" class="m-dox">continuable_base::<wbr />done</a>.</p></aside></section>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article></main>
|
|
<div class="m-dox-search" id="search">
|
|
<a href="#!" onclick="return hideSearch()"></a>
|
|
<div class="m-container">
|
|
<div class="m-row">
|
|
<div class="m-col-m-8 m-push-m-2">
|
|
<div class="m-dox-search-header m-text m-small">
|
|
<div><span class="m-label m-default">Tab</span> / <span class="m-label m-default">T</span> to search, <span class="m-label m-default">Esc</span> to close</div>
|
|
<div id="search-symbolcount">…</div>
|
|
</div>
|
|
<div class="m-dox-search-content">
|
|
<form>
|
|
<input type="search" name="q" id="search-input" placeholder="Loading …" disabled="disabled" autofocus="autofocus" autocomplete="off" spellcheck="false" />
|
|
</form>
|
|
<noscript class="m-text m-danger m-text-center">Unlike everything else in the docs, the search functionality <em>requires</em> JavaScript.</noscript>
|
|
<div id="search-help" class="m-text m-dim m-text-center">
|
|
<p class="m-noindent">Search for symbols, directories, files, pages or
|
|
modules. You can omit any prefix from the symbol or file path; adding a
|
|
<code>:</code> or <code>/</code> suffix lists all members of given symbol or
|
|
directory.</p>
|
|
<p class="m-noindent">Use <span class="m-label m-dim">↓</span>
|
|
/ <span class="m-label m-dim">↑</span> to navigate through the list,
|
|
<span class="m-label m-dim">Enter</span> to go.
|
|
<span class="m-label m-dim">Tab</span> autocompletes common prefix, you can
|
|
copy a link to the result using <span class="m-label m-dim">⌘</span>
|
|
<span class="m-label m-dim">L</span> while <span class="m-label m-dim">⌘</span>
|
|
<span class="m-label m-dim">M</span> produces a Markdown link.</p>
|
|
|
|
</div>
|
|
<div id="search-notfound" class="m-text m-warning m-text-center">Sorry, nothing was found.</div>
|
|
<ul id="search-results"></ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script src="search.js"></script>
|
|
<script src="searchdata.js" async="async"></script>
|
|
<footer><nav>
|
|
<div class="m-container">
|
|
<div class="m-row">
|
|
<div class="m-col-l-10 m-push-l-1">
|
|
<b><a
|
|
href="https://github.com/Naios/continuable">continuable</a></b>
|
|
-
|
|
C++14
|
|
allocation
|
|
aware
|
|
futures</br>Copyright
|
|
2015–2020
|
|
<a
|
|
href="https://github.com/Naios">Denis
|
|
Blank</a>.
|
|
Contact
|
|
the
|
|
author
|
|
via
|
|
<a
|
|
href="mailto:denis.blank@outlook.com">e-mail</a>.</br>Powered
|
|
by
|
|
<a
|
|
href="http://doxygen.org/">Doxygen</a>
|
|
and
|
|
<a
|
|
href="http://mcss.mosra.cz/">m.css</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav></footer>
|
|
</body>
|
|
</html>
|