介绍 Node.js 未来两处很不错的新特性
xiaomo
7年前
<p><img src="https://simg.open-open.com/show/522450e1f0c7d6ce8be23a04edbf1944.jpg" alt="介绍 Node.js 未来两处很不错的新特性" width="550" height="336"></p> <h2>一、Promise 化的 fs API</h2> <p>就在几天前 Node.js 主干合入了一个巨大的 PR:</p> <p><a href="/misc/goto?guid=4959757051739679600" rel="nofollow,noindex">fs: add promises API by jasnell · Pull Request #18297 · nodejs/node</a></p> <p>这个 PR 实验性地加入了 Promise 化的 fs API。虽然现在我们可以使用 <code>util.promisify</code> 来简单地封装 fs 这一套 API,但这只是“封装”。从 Node.js 内核层面上支持 Promise 会有更大的性能优势。</p> <p>以后我们可以这样优雅的读取文件:</p> <pre> <code class="language-javascript">const { readFile } = require('fs').promises async function readAndPrint(filename) { console.log(await readFile(filename)) } readAndPrint('file')</code></pre> <p>错误处理也可以直接使用 <code>try...catch</code> 了,而不是用 <code>Promise.catch</code> :</p> <pre> <code class="language-javascript">const { readFile } = require('fs').promises try { await readFile('file') } catch(e) { console.log(e) }</code></pre> <h2>二、支持 Async Iterators 的 stream API</h2> <p>Async Iterators 目前已经进入 stage-3 阶段,未来将会进入语言标准,V8 目前已经支持这个语言特性。先简单介绍一下 Async Iterators(异步迭代器)是什么。</p> <p>ES6 的 Generator 函数大部分人应该都或多或少知道一些:</p> <pre> <code class="language-javascript">function* idMaker() { var index = 0; while(true) yield index++; } var gen = idMaker(); console.log(gen.next().value); // 0 console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 // ...</code></pre> <p>简单地说,如果我们在 Generator 每次 yield 出的都是一个 Promise,那么它就成为了一个 Async Iterators:</p> <pre> <code class="language-javascript">function* asyncIdMaker() { var index = 0; while(true) yield Promise.resolve(index++); }</code></pre> <p>(关于 Generator 和 Iterator 的关系,可以参考这里)</p> <p>针对 Async Iterators,可以使用专门的 <code>for await</code> 语法来操作:</p> <pre> <code class="language-javascript">for await (const id of asyncIdMaker()) { console.log(id) }</code></pre> <p>Node.js 的 stream API 在今年年初也实验性地加入了这个特性:</p> <p><a href="/misc/goto?guid=4959757051837247985" rel="nofollow,noindex">stream: added experimental support for for-await by mcollina · Pull Request #17755 · nodejs/node</a></p> <p>在过去,我们使用 stream API 时一般都会写出类似这样的代码:</p> <pre> <code class="language-javascript">// 创建一个 stream var myReadStream = fs.createReadStream('filename', 'utf-8') // 响应 data 事件 myReadStream.on('data', function(chunk) { console.log(chunk); // 处理 chunk })</code></pre> <p>这种基于事件回调的实现其实是不太优雅的,逻辑只要稍微复杂一些就很容易写出嵌套层次很深的代码。</p> <p>现在我们可以使用 Async Iterators 这个新特性来处理:</p> <pre> <code class="language-javascript">// 创建一个 stream var myReadStream = fs.createReadStream('filename', 'utf-8') (async () => { for await (const chunk of myReadStream) { console.log(chunk); // 处理 chunk } })()</code></pre> <p>这样就减少了很多不必要的函数嵌套,并且让代码看起来更“同步”。</p> <p>来自:<a href="https://zhuanlan.zhihu.com/p/33689191?utm_source=tuicool&utm_medium=referral">https://zhuanlan.zhihu.com/p/33689191</a></p>