最近,我开始通过Nodeschool练习学习Node.js。但是我对理解此问题的解决方案有疑问:

Your program will get some html written to stdin. Convert all the inner html to
upper-case for elements with a class name of "loud".


官方解决方案是:

var trumpet = require('trumpet');
var through = require('through');

var tr = trumpet();

var loud = tr.select('.loud').createStream();

loud.pipe(through(function(buf){
    this.queue(buf.toString().toUpperCase());
})).pipe(loud);

process.stdin.pipe(tr).pipe(process.stdout);


我不明白的是这部分:

process.stdin.pipe(tr).pipe(process.stdout);


此代码不使用大声变量输出解决方案。谁能向我解释这个魔术代码?

附注:我从PHP来到Node.js,在理解异步Javascript时遇到问题。

最佳答案

我也有类似的困惑,this discussion帮助了我。



我认为您可能会混淆两个流loudtr

tr是主要的小号流


它是一个转换流(具有像管道一样的输入和输出)
它需要html作为输入
输出html
我们将stdin连接到其输入,并将其输出连接到stdout


loud是另一个流,我们通过要求loud选择类为tr的html元素来创建loud


它是双工流(具有像电话一样的输入和输出)
它输出或发送html元素
它还接收html元素


tr的行为是,在将html流式传输到其中时,如果存在类loud的元素,则它们是从大声输出的,它将它们发送到为使文本变为大写而构建的through流中,并将其发送给返回loud的输入,然后将它们重新插入最初从tr接收和输出的html tr中。

我想要注意的重要一点是,尽管loudtr有着重要的联系,但实际上它们根本没有通过管道连接在一起。



虽然trloud是绝对连接的,但连接不是很清楚,它与我们在此处看到的管道无关。

您确实想将HTML发送回tr,但我们通过将其发送回loud来实现。发送到tr输入部分的所有内容都被解释为要处理的新html,因此我们无法发送到tr的输入。取而代之的是,我们发送到loud的输入,它通过喇叭的内部魔术使它从tr输出。

分别考虑流可能会有所帮助:


stdin> tr(进行某种处理)> stdout
loud> through> loud


因此,虽然trloud都是双工流,这意味着它们既有输入又有输出,但是它们的行为方式却截然不同。

tr接收输入,然后作为结果发送输出。

loud发送输出,并等待输入到达结果。

如果愿意,您可以将loud想象成两个流,一个读和一个写,而不只是一个读/写流。这使它看起来更像stdinstdout

loudout> through> loudin

loud绝对知道,当它收到输入时,应该将其传递回tr,这恰好是小号的内部,使其有些神秘

09-10 10:43