NodeJs中谈及较多的可能就是Stream模块了,先写一个简单的ajax回调
$.post("index.php",{data:'aaa',order:'ccc'},function(data){ $("#a").html(data); })
通过post php文件得到回调数据,并进行DOM操作,这行简单的代码在初学者百分之八十的项目中是可行的,包括在我接触Stream之前也是这样认为的,那么问题来了,假如我们这边的data是由php多处输出拼接而成的,数据量极大,而此时客户端又有很大的延时,那么作为一个访问者而言,其用户体验是很差的,他需要等到你的data全部接受完毕之后,才会进行DOM操作。而Stream的应用场景这是这样一个大数据传输的过程。
首先谈及Stream最基本的概念,中文翻译为流,百度看到网上众多介绍流的博客,有一篇让我印象深刻,将服务器比喻成一个水桶,客户端比喻成一个空桶,而中间有一个水管,从服务器向客户端送水的过程其实就是一个流的过程。既然大数据需要等处理完毕才能进行DOM操作,那为什么我们不把data接受一部分就处理一部分呢
Stream在使用时我们会发现很像原生的Ajax,也有点像监听事件start,move,end,官网对Stream的定义是:
所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:
-
data - 当有数据可读时触发。
-
end - 没有更多的数据可读时触发。
-
error - 在接收和写入过程中发生错误时触发。
-
finish - 所有数据已被写入到底层系统时触发。
代码表示下实际流操作的过程:
var rs = fs.createReadStream(path); rs.on('data', function (chunk) { DOM操作 }); rs.on('end', function () { xxxx }) ;
实际中可能遇到最大的问题就是数据的发送速度远大于回调读取操作,这是我们就需要加上一定的打断
var rs = fs.createReadStream(path) ; rs.on('data', function (chunk) { rs.pause() ; DOM(chunk, function () { rs.resume() ; }) ; }) ; rs.on('end', function () { cleanUp(); }) ;
而流在实际应用中最多的应用场景可能就是文件复制,而Node官网提供了另外一种方法pipe()
// pipe自动调用了data,end等事件 fs.createReadStream('/path/to/source').pipe(fs.createWriteStream('/path/to/dest'));