Pipe 之美

时间:2022-05-03
本文章向大家介绍Pipe 之美,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Unix 三大宝是 C,file 和 pipe。C的重要性自不必说,如果 Lisp 是编程语言之母,那么 C 就是编程语言他爹。file 是 unix 世界的夸克 —— 在 unix 的哲学里,万事万物皆 file。文件自然是 file,socket 也是 file,各种硬件 device 还是 file。在你我凡俗眼中,这些东西风马牛不相及;在睿智的 unix 先驱们的眼中,他们都是 stream,而 file,是 stream 的容器。

我们翻开词典看看。stream 这个词本意是 a continuous flow of liquid, air, or gas。在 CS 这行当,它被生动地借用过来,表达 a continuous flow of data or instructions。当你打开一个文件,你可以往里面写东西,也可以读取内容;当你建立一对 socket 连接,你也可以全双工地读写。这个时候,不光是指令(instructions)在指尖流淌,数据(data)也在指缝里奔走。

我们知道,"a continuous flow of liquid" 一般都是通过管道运输的,比如说自来水管,或者输油管。pipe 就是管道。同理,"a continuous flow of data or instructions" 也需要 pipe 进行承载。

于是乎,pipe 就成了和 file 一样,在 unix 中无处不在的精灵。一条简单的命令:

tail -f /var/log/xxx.log | bunyan | grep -A 5 -B 10 ERROR

就让奔流的日志数据在若干个处理程序中游走(map / filter / reduce),直至最终呈现到我们的眼前。

在主流的编程语言中,对数据(或者数据处理流程)的 pipe 也越来越得到重视。不少语言直接在其 core 中内置了 pipe,如 elixir/scala 等语言 的 |>,nodejs 的 stream interface 等。上周五我在公司里分享了一个主题,就是关于 pipe 的。我将其分成了四种基本的处理:

  • pipe for single value
  • pipe for multiple values
  • pipe for single future value
  • pipe for multiple future values

在处理 multiple values 时,大家一定要注意容器(container)的选取。不是所有的场景都适合使用 array 作为 multiple values 的 container 的。很多时候,选择了合适的容器(数据结构),问题的解决就完成了一半。

分享的最后重点介绍了一下 node 的 transform stream,对于 nodejs developer 来说,这可能是使用频率最广的 stream 了。使用 transform stream 我们可以一路 pipe 出如下干净整洁的代码:

inputDataSet
    .pipe(transformation1)
    .pipe(transformation2)
    .pipe(transformation3)
    .reduce(reducer)

给出的代码继承自 ObjectTransform,这是我们内部封装的一个 Transform stream,你就把它当做正常的 Transform stream 理解就好了。:)

好,下面放毒(抱歉,slides 做得急而糙,有不少 typo,请容忍)。