Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

Node 的 stream 缺个「read until end」

  Node 的 stream 是个难用到爆的东西,只是碍于它原生的很多东西都基于这套 stream,所以我们只能勉强用着。很多时候还是会遇到麻烦,比如当我们需要在一个 HTTP 请求中接收全部 POST 过来的数据后再做解析时,由于数据是以流的形式存在,于是就会要写一堆恶心的事件。
  这也许是所有新手 Node 玩家都会遇到的问题吧?如何读入完整的 POST 数据? #!/usr/bin/env babel-node import http from 'http'; http.createServer((req, res) => { let buffers = []; req.on('data', buffer => buffers.push(buffer)); req.on('end', () => { let input = Buffer.concat(buffers); // 求和并输出 try { input = JSON.parse(input); let result = input.reduce((sum, i) => sum + i, 0); res.write(result + '\n'); } catch(e) { res.statusCode = 400; } res.end(); }); }).listen(8000);
  这段代码中使用了恶心的事件来处理输入流。在 data 事件中收集数据,end 事件合并数据,而且还需要一个中间变量来存这个数据传输过程的 buffer。我刚玩 Node 时就被这样的代码恶心到了。但后来由于把 HTTP 封装掉了,所以一直也没再纠结这种东西。直到现在使用大量的流来解决问题时才再一次被恶心到。
  我觉得 Node 是时候好好折腾一下自己的流实现了。在这个 Promise 普及的年代还用回调是什么鬼?而且流对象真的缺一个原生的 read until end 之类的东西来提供读入整个流数据。
  为了避免这种恶心的写法,我自己还搞了个处理流的小工具。就像是给不稳定的电流加个电容,让它变得和谐起来一样,我将它称为 capacitance。于是实现同样的功能,下面的代码就变得和谐得多。 #!/usr/bin/env babel-node import http from 'http'; import Capacitance from 'capacitance'; http.createServer((req, res) => { req.pipe(new Capacitance()).then(input => { // 求和并输出 input = JSON.parse(input); let result = input.reduce((sum, i) => sum + i, 0); res.write(result + '\n'); }) .catch(() => res.statusCode = 400) .then(() => res.end()); }).listen(8000);
网名:
54.198.108.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^