介绍 Node.js 未来两处很不错的新特性

xiaomo 6年前
   <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>