CircosHeatmap-aardio/dist/lib/r/site-library/promises/doc/promises_01_motivation.html

317 lines
7.9 KiB
HTML
Raw Normal View History

2025-01-12 00:52:51 +08:00
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Why use promises?</title>
<script>// Pandoc 2.9 adds attributes on both header and div. We remove the former (to
// be compatible with the behavior of Pandoc < 2.8).
document.addEventListener('DOMContentLoaded', function(e) {
var hs = document.querySelectorAll("div.section[class*='level'] > :first-child");
var i, h, a;
for (i = 0; i < hs.length; i++) {
h = hs[i];
if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6
a = h.attributes;
while (a.length > 0) h.removeAttribute(a[0].name);
}
});
</script>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<style type="text/css">body {
background-color: #fff;
margin: 1em auto;
max-width: 700px;
overflow: visible;
padding-left: 2em;
padding-right: 2em;
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.35;
}
#TOC {
clear: both;
margin: 0 0 10px 10px;
padding: 4px;
width: 400px;
border: 1px solid #CCCCCC;
border-radius: 5px;
background-color: #f6f6f6;
font-size: 13px;
line-height: 1.3;
}
#TOC .toctitle {
font-weight: bold;
font-size: 15px;
margin-left: 5px;
}
#TOC ul {
padding-left: 40px;
margin-left: -1.5em;
margin-top: 5px;
margin-bottom: 5px;
}
#TOC ul ul {
margin-left: -2em;
}
#TOC li {
line-height: 16px;
}
table {
margin: 1em auto;
border-width: 1px;
border-color: #DDDDDD;
border-style: outset;
border-collapse: collapse;
}
table th {
border-width: 2px;
padding: 5px;
border-style: inset;
}
table td {
border-width: 1px;
border-style: inset;
line-height: 18px;
padding: 5px 5px;
}
table, table th, table td {
border-left-style: none;
border-right-style: none;
}
table thead, table tr.even {
background-color: #f7f7f7;
}
p {
margin: 0.5em 0;
}
blockquote {
background-color: #f6f6f6;
padding: 0.25em 0.75em;
}
hr {
border-style: solid;
border: none;
border-top: 1px solid #777;
margin: 28px 0;
}
dl {
margin-left: 0;
}
dl dd {
margin-bottom: 13px;
margin-left: 13px;
}
dl dt {
font-weight: bold;
}
ul {
margin-top: 0;
}
ul li {
list-style: circle outside;
}
ul ul {
margin-bottom: 0;
}
pre, code {
background-color: #f7f7f7;
border-radius: 3px;
color: #333;
white-space: pre-wrap;
}
pre {
border-radius: 3px;
margin: 5px 0px 10px 0px;
padding: 10px;
}
pre:not([class]) {
background-color: #f7f7f7;
}
code {
font-family: Consolas, Monaco, 'Courier New', monospace;
font-size: 85%;
}
p > code, li > code {
padding: 2px 0px;
}
div.figure {
text-align: center;
}
img {
background-color: #FFFFFF;
padding: 2px;
border: 1px solid #DDDDDD;
border-radius: 3px;
border: 1px solid #CCCCCC;
margin: 0 5px;
}
h1 {
margin-top: 0;
font-size: 35px;
line-height: 40px;
}
h2 {
border-bottom: 4px solid #f7f7f7;
padding-top: 10px;
padding-bottom: 2px;
font-size: 145%;
}
h3 {
border-bottom: 2px solid #f7f7f7;
padding-top: 10px;
font-size: 120%;
}
h4 {
border-bottom: 1px solid #f7f7f7;
margin-left: 8px;
font-size: 105%;
}
h5, h6 {
border-bottom: 1px solid #ccc;
font-size: 105%;
}
a {
color: #0033dd;
text-decoration: none;
}
a:hover {
color: #6666ff; }
a:visited {
color: #800080; }
a:visited:hover {
color: #BB00BB; }
a[href^="http:"] {
text-decoration: underline; }
a[href^="https:"] {
text-decoration: underline; }
code > span.kw { color: #555; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #d14; }
code > span.fl { color: #d14; }
code > span.ch { color: #d14; }
code > span.st { color: #d14; }
code > span.co { color: #888888; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #900; font-weight: bold; }
code > span.er { color: #a61717; background-color: #e3d2d2; }
</style>
</head>
<body>
<h1 class="title toc-ignore">Why use promises?</h1>
<p>The <code>promises</code> library is designed to make it possible for
R users to integrate <em>asynchronous programming</em> techniques into
their code. It is intended to improve the scalability of certain classes
of Shiny applications, and can also be used completely separately from
Shiny.</p>
<p>Asynchronous programming means starting an operation without waiting
around for its results. Contrast this with standard (synchronous) R
programming, where the caller of a function must wait for the function
to either return a result or throw an error.</p>
<p>Asynchronous programming is a particularly important capability for
languages that are both 1) single threaded, and 2) need to serve
multiple users concurrently. R is single threaded, but until recent
years has mostly been restricted to desktop use or batch execution. The
rise of Shiny and other web frameworks for R has meant much greater
demand for serving multiple users concurrently, and thus a greater need
for asynchronous programming.</p>
<div id="what-are-promises-good-for" class="section level2">
<h2>What are promises good for?</h2>
<p>Promises work well when you have a Shiny application with a
particular operation, especially a calculation, that takes a long time
(measured in seconds or even minutes). Without promises, such operations
not only block the current users session from proceeding, but also
block <em>all</em> other requests being made to the R process, no matter
how trivial. Even loading a small CSS file, which should be nearly
instantaneous, can be delayed by many seconds if another users Shiny
session is busy crunching through hundreds of gigabytes of data or
querying a particularly slow backend database.</p>
<p>With promises, you can convert long-running operations to be
asynchronous, which frees up the R process to do other work. For Shiny
applications, this has the potential to greatly increase scalability for
each R process (depending on how slow the operations are in the first
place, and what resources they make use of).</p>
<p><strong>DO use promises if you have a Shiny app with long-running
operations, and want to serve multiple users
simultaneously.</strong></p>
</div>
<div id="what-arent-promises-good-for" class="section level2">
<h2>What <em>arent</em> promises good for?</h2>
<p>While promises can make a huge difference in the scalability of a
Shiny app, they make relatively little difference in the latency of a
single session. That is to say, if a Shiny application is slow when only
a single user is hitting it, converting it to use promises is unlikely
to make it perform any faster (and in fact may slightly slow it down).
Promises will just help prevent <em>other</em> sessions from being
slowed down by one sessions computations.</p>
<p>(The exception to this is if the Shiny app has several distinct long
computations that dont depend very much on each other—then you could
use asynchronous programming to exploit a little parallelism. But I
think this will be a less common use of async programming, as R already
has other good tools designed specifically for data parallelism.)</p>
<p><strong>DONT use promises to improve the performance of Shiny apps
for a single user.</strong></p>
<div style="font-size: 20px; margin-top: 40px; text-align: right;">
<p>Next: <a href="promises_02_intro.html">An informal intro to async
programming</a></p>
</div>
</div>
<!-- code folding -->
<!-- dynamically load mathjax for compatibility with self-contained -->
<script>
(function () {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
document.getElementsByTagName("head")[0].appendChild(script);
})();
</script>
</body>
</html>