Files
DefectingCat.github.io/defect/get-starting-for-node-js.html
DefectingCat 8c7085f18f
2020-11-02 02:17:54 +00:00

38 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="zh-CN" data-default-color-scheme="&#34;auto&#34;"><head><meta charset="UTF-8"><link rel="apple-touch-icon" sizes="76x76" href="/images/img/apple-touch-icon.webp"><link rel="icon" type="image/png" href="/images/img/favicon.webp"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,shrink-to-fit=no"><meta http-equiv="x-ua-compatible" content="ie=edge"><meta name="theme-color" content="#9DC8C8"><meta name="description" content=""><meta name="author" content="Defectink"><meta name="keywords" content=""><title>Node.js之旅 - 🍭Defectink</title><link rel="stylesheet" href="https://cdn.defectink.com/static/twitter-bootstrap/4.5.3/css/bootstrap.min.css"><link rel="stylesheet" href="https://cdn.defectink.com/static/github-markdown-css/4.0.0/github-markdown.min.css"><link rel="stylesheet" href="/lib/hint/hint.min.css"><link rel="stylesheet" href="https://cdn.defectink.com/static/highlight.js/10.0.0/styles/github-gist.min.css"><link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css"><link rel="stylesheet" href="https://cdn.defectink.com/static/t/font_1736178_kmeydafke9r.css"><link rel="stylesheet" href="/css/main.css"><link rel="stylesheet" href="/css/xfy.css"><script src="/js/utils.js"></script><script src="/js/color-schema.js"></script><meta name="generator" content="Hexo 5.2.0"><link rel="alternate" href="/xml/atom.xml" title="🍭Defectink" type="application/atom+xml"><link rel="alternate" href="/xml/rss.xml" title="🍭Defectink" type="application/rss+xml"></head><body><header style="height:75vh"><nav id="navbar" class="navbar fixed-top navbar-expand-lg navbar-dark scrolling-navbar"><div class="container"><a class="navbar-brand" href="/">&nbsp;<strong>🍭Defectink</strong>&nbsp;</a> <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><div class="animated-icon"><span></span><span></span><span></span></div></button><div class="collapse navbar-collapse" id="navbarSupportedContent"><ul class="navbar-nav ml-auto text-center"><li class="nav-item"><a class="nav-link" href="/">🏠 首页</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">📕 索引</a><div class="dropdown-menu" aria-labelledby="navbarDropdown"><a class="dropdown-item" href="/categories/">🎁 分类</a> <a class="dropdown-item" href="/tags/">🎐 标签</a></div></li><li class="nav-item"><a class="nav-link" href="/archives/">📂 归档</a></li><li class="nav-item"><a class="nav-link" href="/about/">🎃 关于</a></li><li class="nav-item"><a class="nav-link" href="/links/">🙆‍♀️ 小伙伴</a></li><li class="nav-item"><a class="nav-link" href="/pgp/">🔐 PGP</a></li><li class="nav-item" id="search-btn"><a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;<i class="iconfont icon-search"></i>&nbsp;</a></li><li class="nav-item" id="color-toggle-btn"><a class="nav-link" href="javascript:">&nbsp;<i class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a></li></ul></div></div></nav><div class="banner intro-2" id="background" parallax="true" style="background:url(/images/img/post.webp) no-repeat center center;background-size:cover"><div class="full-bg-img"><div class="mask flex-center" style="background-color:rgba(0,0,0,.3)"><div class="container page-header text-center fade-in-up"><span class="h2" id="subtitle"></span><div class="mt-3"><span class="post-meta mr-2"><i class="iconfont icon-author" aria-hidden="true"></i> Defectink</span><span class="post-meta"><i class="iconfont icon-date-fill" aria-hidden="true"></i> <time datetime="2020-09-03 16:09" pubdate>2020年9月3日 下午</time></span></div><div class="mt-1"><span class="post-meta mr-2"><i class="iconfont icon-chart"></i> 1.6k 字</span><span class="post-meta mr-2"><i class="iconfont icon-clock-fill"></i> 18 分钟</span></div></div></div></div></div></header><main><div class="container-fluid"><div class="row"><div class="d-none d-lg-block col-lg-2"></div><div class="col-lg-8 nopadding-md"><div class="container nopadding-md" id="board-ctn"><div class="py-5" id="board"><article class="post-content mx-auto" id="post"><h1 style="display:none">Node.js之旅</h1><p class="note note-info">本文最后水于2020年11月2日 凌晨</p><div class="markdown-body" id="post-body"><blockquote><p>Node.js® is a JavaScript runtime built on Chromes V8 JavaScript engine.</p></blockquote><p>Node.js不仅仅是服务器上的JavaScript。</p><p><img src="../images/Node.js%E4%B9%8B%E6%97%85/2020-09-03-14-54-53.webp" srcset="/images/img/loading.gif"></p><h2 id="并不熟悉的JavaScript"><a href="#并不熟悉的JavaScript" class="headerlink" title="并不熟悉的JavaScript"></a>并不熟悉的JavaScript</h2><p>虽然说Node直接般来了个V8来运行JavaScript但它毕竟不运行在浏览器上并且是由事件驱动的异步程序它的本来的目的就是用来搭建高性能的Web服务器。在极少情况下编写的 JavaScript 代码没有按期望的方式运行。</p><p>在客户端的运行环境下只要是在同一个浏览器窗口运行的JS环境就属于同一个全局环境。无论是在哪里引入的JS文件都属于同一个运行环境全局变量能够正常工作例如有两个js被引入</p><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;a.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;b.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre><p>他们分别有一段代码:</p><pre><code class="hljs js"><span class="hljs-comment">// a.js</span>
<span class="hljs-keyword">let</span> a = <span class="hljs-string">&#x27;xxxxxfy!&#x27;</span>;
<span class="hljs-comment">// b.js</span>
alert(a);</code></pre><p>正常情况下全局变量<code>a</code>是可以被正常访问的而在node中a.js和b.js分别是两个文件不做其他操作的情况下他们分别是两个全局变量。</p><h2 id="基础架构"><a href="#基础架构" class="headerlink" title="基础架构"></a>基础架构</h2><p>Node 运行时的基础架构由两大组件构成:</p><ul><li>JavaScript 引擎</li><li>非阻塞 I/O 库</li></ul><h3 id="JavaScript引擎"><a href="#JavaScript引擎" class="headerlink" title="JavaScript引擎"></a>JavaScript引擎</h3><p>众所周知node使用的是Chrome大排自吸V8它可以运行任何JS代码。启动时它会启动一个V8的引擎实例且node可以充分的利用这个引擎实例。</p><p>V8可嵌入/绑定到任何C++程序中,。这意味着,除了纯 JavaScript 库外,还可以扩展 V8 来创建全新的函数(或函数模板),方法是将其与 V8 绑定在一起。并且node还支持使用编译好的二进制的C++程序。</p><h3 id="事件循环"><a href="#事件循环" class="headerlink" title="事件循环"></a>事件循环</h3><p>JavaScript是一门单线程的语言无论换到什么地方运行它也是单线程语言。单线程语言面临的最大的问题就是阻塞在前面的代码没有被执行完后面的代码都将处于等待状态。</p><p>node使用<a target="_blank" rel="noopener" href="http://libuv.org/">libuv</a>来实现事件循环。要使用事件循环可以使用异步API可将回调函数作为参数传递到该 API 函数在事件循环期间会执行该回调函数。node异步编程的直接体现就是回调函数。异步编程基于回调函数来实现但不能说是使用了回调后程序就异步化了。Node 所有 API 都支持回调函数。</p><pre><code class="hljs smali"> ┌───────────────────────────┐
┌─&gt;│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │&lt;─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ <span class="hljs-built_in"> check </span>
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘</code></pre><p>例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求。</p><p>事件循环包含多个调用回调函数的阶段:</p><ul><li>计时器阶段:将运行 setInterval() 和 setTimeout() 过期计时器回调函数</li><li>轮询阶段:将轮询操作系统以查看是否完成了所有 I/O 操作,如果已完成,将运行回调函数</li><li>检查阶段:将运行 setImmediate() 回调函数</li></ul><p>一个常见的误区是,认为 V8 和事件循环回调函数在不同线程上运行。但事实并非如此。V8 在同一个线程上运行所有 JavaScript 代码。</p><h2 id="非阻塞I-O"><a href="#非阻塞I-O" class="headerlink" title="非阻塞I/O"></a>非阻塞I/O</h2><p>已经简单的了解过node基于v8的单线程来使用回调函数实现异步编程从而达到高性能与高并发。</p><h3 id="异步I-O"><a href="#异步I-O" class="headerlink" title="异步I/O"></a>异步I/O</h3><p>异步I/O能够大大的提升程序的工作效率且不会影响剩下的代码执行。</p><h4 id="同步读取文件"><a href="#同步读取文件" class="headerlink" title="同步读取文件"></a>同步读取文件</h4><p>首先来看下同步读取文件</p><pre><code class="hljs js"><span class="hljs-keyword">let</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;fs&#x27;</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;starting process...&#x27;</span>);
<span class="hljs-keyword">let</span> data = fs.readFileSync(<span class="hljs-string">&#x27;test.txt&#x27;</span>);
<span class="hljs-built_in">console</span>.log(data);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;the end&#x27;</span>);</code></pre><p>同步读取文件会按照从上到下的顺序来执行代码到遇到读取I/O时剩下的代码将处于等待状态。并且在读取I/O时遇到错误例如文件不存在将会直接返回错误剩下的代码将不执行完。</p><h4 id="异步读取文件"><a href="#异步读取文件" class="headerlink" title="异步读取文件"></a>异步读取文件</h4><pre><code class="hljs js"><span class="hljs-keyword">let</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;fs&#x27;</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;starting process...&#x27;</span>);
fs.readFile(<span class="hljs-string">&#x27;test.txt&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">err, data</span>) =&gt;</span> &#123;
<span class="hljs-keyword">if</span> (err) &#123;
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;something was wrong: &#x27;</span> + err);
&#125; <span class="hljs-keyword">else</span> &#123;
<span class="hljs-built_in">console</span>.log(data);
&#125;
&#125;)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;the end&#x27;</span>);</code></pre><p>异步读取文件调用了回调函数它设置了一个事件循环在等待读取I/O的同时将继续执行剩下的代码。当文件读取完成之后将会返回回调函数并输出结果。并且当读取文件遇到错误时在等待读取期间执行的代码将正常执行。</p><p>异步的结果看起来像是这样的:</p><pre><code class="hljs angelscript">starting process...
the end
&lt;Buffer <span class="hljs-number">64</span> <span class="hljs-number">66</span> <span class="hljs-number">6</span>a <span class="hljs-number">61</span> <span class="hljs-number">73</span>&gt;</code></pre><p>在等待其读取<code>test.txt</code>的期间JS将剩下的<code>console.log</code>语句先执行了。</p><h3 id="同步I-O"><a href="#同步I-O" class="headerlink" title="同步I/O"></a>同步I/O</h3><p>node的设计理念就是使用异步编程使用阻塞编程可无法写出一个高性能的web服务器。</p><p>但这不代表着同步I/O就一无是处在某些情况下同步 I/O 通常比异步 I/O 更快,原因在于设置和使用回调函数、轮询操作系统来获取 I/O 状态等操作都涉及到一定的开销。</p><p>如果需要写一个一次性的使用程序,仅用于处理一个文件,从命令行中启动 Node并向其传递 JavaScript 实用程序的文件名。此时,该实用程序是唯一运行的程序,因此,即使它阻塞了 V8 线程,也没有任何影响。在此情况下,适合使用同步 I/O。</p><p>只要是谨慎使用同步 Node API 调用,就不会出现什么问题。</p><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><ul><li>V8是有八个气缸的V型发动机.</li><li>JavaScript是单线程语言它通过V8 引擎提供的异步执行回调接口实现了异步编程。</li></ul><p>全文均是笔记</p><ul><li><a target="_blank" rel="noopener" href="https://developer.ibm.com/zh/tutorials/learn-nodejs-tour-node/">Node.js 之旅</a></li><li><a target="_blank" rel="noopener" href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/">The Node.js Event Loop</a></li><li><a target="_blank" rel="noopener" href="https://www.runoob.com/nodejs/nodejs-callback.html">Node.js 回调函数</a></li><li><a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/V8%E5%8F%91%E5%8A%A8%E6%9C%BA">V8发动机</a></li></ul></div><hr><div><div class="post-metas mb-3"><div class="post-meta mr-3"><i class="iconfont icon-category"></i> <a class="hover-with-bg" href="/categories/%E7%AC%94%E8%AE%B0/">笔记</a></div><div class="post-meta"><i class="iconfont icon-tags"></i> <a class="hover-with-bg" href="/tags/JavaScript/">JavaScript</a> <a class="hover-with-bg" href="/tags/Node/">Node</a></div></div><p class="note note-warning"><a target="_blank" href="https://zh.wikipedia.org/wiki/Wikipedia:CC_BY-SA_3.0%E5%8D%8F%E8%AE%AE%E6%96%87%E6%9C%AC" rel="nofollow noopener noopener">CC BY-SA 3.0❤</a></p><div class="post-prevnext row"><article class="post-prev col-6"><a href="/defect/Vue-js-get-started.html"><i class="iconfont icon-arrowleft"></i> <span class="hidden-mobile">Vue.js-起步!</span> <span class="visible-mobile">上一篇</span></a></article><article class="post-next col-6"><a href="/defect/irc-getting-started.html"><span class="hidden-mobile">入坑IRC</span> <span class="visible-mobile">下一篇</span><i class="iconfont icon-arrowright"></i></a></article></div></div><article class="comments" id="comments"><div id="vcomments"></div><script type="text/javascript">function loadValine(){addScript("https://cdn.defectink.com/static/valine/1.4.14/Valine.min.js",function(){new Valine({el:"#vcomments",app_id:"dD9t7mcIBVzJWag5ez6GPy2v-MdYXbMMI",app_key:"bWG6pmKsEscrH4JjrpNNAAy6",placeholder:"嘤嘤嘤???",path:window.location.pathname,avatar:"retro",meta:["nick","mail","link"],pageSize:"10",lang:"zh-CN",highlight:!0,recordIP:!1,serverURLs:""})})}waitElementVisible("vcomments",loadValine)</script><noscript>Please enable JavaScript to view the <a target="_blank" href="https://valine.js.org" rel="nofollow noopener noopener">comments powered by Valine.</a></noscript></article></article></div></div></div><div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn"><div id="toc"><p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p><div id="tocbot"></div></div></div></div></div></main><a id="scroll-top-button" href="#" role="button"><i class="iconfont icon-arrowup" aria-hidden="true"></i></a><div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel" aria-hidden="true"><div class="modal-dialog modal-dialog-scrollable modal-lg" role="document"><div class="modal-content"><div class="modal-header text-center"><h4 class="modal-title w-100 font-weight-bold">搜索</h4><button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button></div><div class="modal-body mx-3"><div class="md-form mb-5"><input type="text" id="local-search-input" class="form-control validate"> <label data-error="x" data-success="v" for="local-search-input">关键词</label></div><div class="list-group" id="local-search-result"></div></div></div></div></div><footer class="text-center mt-5 py-3"><div class="footer-content"><a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a><i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a></div><div class="beian"><a href="http://beian.miit.gov.cn/" target="_blank" rel="nofollow noopener">皖ICP备17017808号</a></div></footer><script src="https://cdn.defectink.com/static/jquery/3.4.1/jquery.min.js"></script><script src="https://cdn.defectink.com/static/twitter-bootstrap/4.5.3/js/bootstrap.min.js"></script><script src="/js/debouncer.js"></script><script src="/js/main.js"></script><script src="/js/lazyload.js"></script><script defer="defer" src="https://cdn.defectink.com/static/clipboard.js/2.0.6/clipboard.min.js"></script><script src="/js/clipboard-use.js"></script><script src="/js/xfy.js"></script><script src="https://cdn.defectink.com/static/tocbot/4.11.1/tocbot.min.js"></script><script>$(document).ready(function(){var t=$("#board-ctn").offset().top;tocbot.init({tocSelector:"#tocbot",contentSelector:"#post-body",headingSelector:"h1,h2,h3,h4,h5,h6",linkClass:"tocbot-link",activeLinkClass:"tocbot-active-link",listClass:"tocbot-list",isCollapsedClass:"tocbot-is-collapsed",collapsibleClass:"tocbot-is-collapsible",collapseDepth:3,scrollSmooth:!0,headingsOffset:-t}),0<$(".toc-list-item").length&&$("#toc").css("visibility","visible")})</script><script src="https://cdn.defectink.com/static/typed.js/2.0.11/typed.min.js"></script><script>var typed=new Typed("#subtitle",{strings:[" ","Node.js之旅&nbsp;"],cursorChar:"❤",typeSpeed:70,loop:!1});typed.stop(),$(document).ready(function(){$(".typed-cursor").addClass("h2"),typed.start()})</script><script src="/js/local-search.js"></script><script>var path="/xml/local-search.xml",inputArea=document.querySelector("#local-search-input");inputArea.onclick=function(){searchFunc(path,"local-search-input","local-search-result"),this.onclick=null}</script><script src="https://cdn.defectink.com/static/fancybox/3.5.7/jquery.fancybox.min.js"></script><link rel="stylesheet" href="https://cdn.defectink.com/static/fancybox/3.5.7/jquery.fancybox.min.css"><script>$("#post img:not(.no-zoom img, img[no-zoom]), img[zoom]").each(function(){var t=document.createElement("a");$(t).attr("data-fancybox","images"),$(t).attr("href",$(this).attr("src")),$(this).wrap(t)})</script><script src="https://cdn.defectink.com/static/mermaid/8.5.0/mermaid.min.js"></script><script>window.mermaid&&mermaid.initialize({theme:"default"})</script></body></html>