learnyounode
Version:
Learn You The Node.js For Much Win! An intro to Node.js via a set of self-guided workshops.
373 lines (312 loc) • 12.4 kB
HTML
<!-- Created with GFM2HTML: https://github.com/rvagg/gfm2html -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="created-with" content="https://github.com/rvagg/gfm2html">
<style type="text/css">
/* most of normalize.css */
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}[hidden],template{display:none;}html{font-family:sans-serif;/*1*/-ms-text-size-adjust:100%;/*2*/-webkit-text-size-adjust:100%;/*2*/}body{margin:0;}a{background:transparent;}a:focus{outline:thindotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em0;}abbr[title]{border-bottom:1pxdotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C""\201D""\2018""\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}table{border-collapse:collapse;border-spacing:0;}
html {
font: 14px 'Helvetica Neue', Helvetica, arial, freesans, clean, sans-serif;
}
.container {
line-height: 1.6;
color: #333;
background: #eee;
border-radius: 3px;
padding: 3px;
width: 790px;
margin: 10px auto;
}
.body-content {
background-color: #fff;
border: 1px solid #CACACA;
padding: 30px;
}
.body-content > *:first-child {
margin-top: 0 ;
}
a, a:visited {
color: #4183c4;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
p, blockquote, ul, ol, dl, table, pre {
margin: 15px 0;
}
.markdown-body h1
, .markdown-body h2
, .markdown-body h3
, .markdown-body h4
, .markdown-body h5
, .markdown-body h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
}
h1 {
font-size: 2.5em;
color: #000;
border-bottom: 1px solid #ddd;
}
h2 {
font-size: 2em;
border-bottom: 1px solid #eee;
color: #000;
}
img {
max-width: 100%;
}
hr {
background: transparent url("/img/hr.png") repeat-x 0 0;
border: 0 none;
color: #ccc;
height: 4px;
padding: 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
tr:nth-child(2n) {
background-color: #f8f8f8;
}
.markdown-body tr {
border-top: 1px solid #ccc;
background-color: #fff;
}
td, th {
border: 1px solid #ccc;
padding: 6px 13px;
}
th {
font-weight: bold;
}
blockquote {
border-left: 4px solid #ddd;
padding: 0 15px;
color: #777;
}
blockquote > :last-child, blockquote > :first-child {
margin-bottom: 0px;
}
pre, code {
font-size: 13px;
font-family: 'UbuntuMono', monospace;
white-space: nowrap;
margin: 0 2px;
padding: 0px 5px;
border: 1px solid #eaeaea;
background-color: #f8f8f8;
border-radius: 3px;
}
pre > code {
white-space: pre;
}
pre {
overflow-x: auto;
white-space: pre;
padding: 10px;
line-height: 150%;
background-color: #f8f8f8;
border-color: #ccc;
}
pre code, pre tt {
margin: 0;
padding: 0;
border: 0;
background-color: transparent;
border: none;
}
.highlight .c
, .highlight .cm
, .highlight .cp
, .highlight .c1 {
color:#999988;
font-style:italic;
}
.highlight .err {
color:#a61717;
background-color:#e3d2d2
}
.highlight .o
, .highlight .gs
, .highlight .kc
, .highlight .kd
, .highlight .kn
, .highlight .kp
, .highlight .kr {
font-weight:bold
}
.highlight .cs {
color:#999999;
font-weight:bold;
font-style:italic
}
.highlight .gd {
color:#000000;
background-color:#ffdddd
}
.highlight .gd .x {
color:#000000;
background-color:#ffaaaa
}
.highlight .ge {
font-style:italic
}
.highlight .gr
, .highlight .gt {
color:#aa0000
}
.highlight .gh
, .highlight .bp {
color:#999999
}
.highlight .gi {
color:#000000;
background-color:#ddffdd
}
.highlight .gi .x {
color:#000000;
background-color:#aaffaa
}
.highlight .go {
color:#888888
}
.highlight .gp
, .highlight .nn {
color:#555555
}
.highlight .gu {
color:#800080;
font-weight:bold
}
.highlight .kt {
color:#445588;
font-weight:bold
}
.highlight .m
, .highlight .mf
, .highlight .mh
, .highlight .mi
, .highlight .mo
, .highlight .il {
color:#009999
}
.highlight .s
, .highlight .sb
, .highlight .sc
, .highlight .sd
, .highlight .s2
, .highlight .se
, .highlight .sh
, .highlight .si
, .highlight .sx
, .highlight .s1 {
color:#d14
}
.highlight .n {
color:#333333
}
.highlight .na
, .highlight .no
, .highlight .nv
, .highlight .vc
, .highlight .vg
, .highlight .vi
, .highlight .nb {
color:#0086B3
}
.highlight .nc {
color:#445588;
font-weight:bold
}
.highlight .ni {
color:#800080
}
.highlight .ne
, .highlight .nf {
color:#990000;
font-weight:bold
}
.highlight .nt {
color:#000080
}
.highlight .ow {
font-weight:bold
}
.highlight .w {
color:#bbbbbb
}
.highlight .sr {
color:#009926
}
.highlight .ss {
color:#990073
}
.highlight .gc {
color:#999;
background-color:#EAF2F5
}</style>
</head>
<body>
<div class="container">
<div class="body-content"><h1 id="through2-map">through2-map</h1>
<p><a href="https://nodei.co/npm/through2-map/"><img src="https://nodei.co/npm/through2-map.png" alt="NPM"></a></p>
<p>This is a super thin wrapper around <a href="https://npmjs.com/through2">through2</a> that works like <code>Array.prototype.map</code> but for streams.</p>
<p>For when through2 is just too verbose :wink:</p>
<p>Note you will <strong>NOT</strong> be able to skip chunks. This is intended for modification only. If you want filter the stream content, use either <code>through2</code> or <code>through2-filter</code>.</p>
<p><strong>IMPORTANT:</strong> If you return <code>null</code> from your function, the stream will end there.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">map</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">"through2-map"</span><span class="p">)</span>
<span class="kd">var</span> <span class="nx">truncate</span> <span class="o">=</span> <span class="nx">map</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">chunk</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="p">})</span>
<span class="c1">// vs. with through2:</span>
<span class="kd">var</span> <span class="nx">truncate</span> <span class="o">=</span> <span class="nx">through2</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">,</span> <span class="nx">encoding</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">chunk</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span>
<span class="k">return</span> <span class="nx">callback</span><span class="p">()</span>
<span class="p">})</span>
<span class="c1">// Then use your map:</span>
<span class="nx">source</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">truncate</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">sink</span><span class="p">)</span>
<span class="c1">// Additionally accepts `wantStrings` argument to conver buffers into strings</span>
<span class="kd">var</span> <span class="nx">stripTags</span> <span class="o">=</span> <span class="nx">map</span><span class="p">({</span><span class="nx">wantStrings</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// OMG don't actually use this</span>
<span class="k">return</span> <span class="nx">str</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/<.*?>/g</span><span class="p">,</span> <span class="s2">""</span><span class="p">)</span>
<span class="p">})</span>
<span class="c1">// Works like `Array.prototype.map` meaning you can specify a function that</span>
<span class="c1">// takes up to two* arguments: fn(chunk, index)</span>
<span class="kd">var</span> <span class="nx">spaceout</span> <span class="o">=</span> <span class="nx">map</span><span class="p">({</span><span class="nx">wantStrings</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">index</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="o">?</span> <span class="nx">chunk</span> <span class="o">+</span> <span class="s2">"\n\n"</span> <span class="o">:</span> <span class="nx">chunk</span>
<span class="p">})</span>
<span class="c1">// vs. with through2:</span>
<span class="kd">var</span> <span class="nx">spaceout</span> <span class="o">=</span> <span class="nx">through2</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">,</span> <span class="nx">encoding</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">index</span> <span class="o">==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">index</span> <span class="o">=</span> <span class="mi">0</span>
<span class="kd">var</span> <span class="nx">buf</span> <span class="o">=</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">index</span><span class="o">++</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="o">?</span> <span class="nx">Buffer</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">chunk</span><span class="p">,</span> <span class="k">new</span> <span class="nx">Buffer</span><span class="p">(</span><span class="s2">"\n\n"</span><span class="p">))</span> <span class="o">:</span> <span class="nx">chunk</span>
<span class="k">this</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">buf</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">callback</span><span class="p">()</span>
<span class="p">})</span>
</pre></div>
<p>*Differences from <code>Array.prototype.map</code>:</p>
<ul>
<li>Cannot insert <code>null</code> elements into the stream without aborting.</li>
<li>No third <code>array</code> callback argument. That would require realizing the entire stream, which is generally counter-productive to stream operations.</li>
<li><code>Array.prototype.map</code> doesn't modify the source Array, which is somewhat nonsensical when applied to streams.</li>
</ul>
<h2 id="options">Options</h2>
<ul>
<li>wantStrings: Automatically call chunk.toString() for the super lazy.</li>
<li>all other through2 options</li>
</ul>
<h1 id="license">LICENSE</h1>
<p>MIT</p>
</div>
</div>
</body>
</html>