举例讲解Node.js中的Writable对象


Posted in Javascript onJuly 29, 2015

只要有玩过 nodejs,那就一定接触过 Writable。http 模块的请求回调参数中的 res 参数就是一个 Writable 对象。我们经常会往上面 write 一堆东西,最后调用个 end 方法吧?这些都属于 Writable 的行为。

我们手动创建的 Writable 对象是交给用户使用的,那么 write 和 end 方法都是用户调用的。作为提供方,我们如何知道自己的 Writable 对象被用户执行了什么操作呢?就猜这个 API 吧,我首先会猜到某个事件。然而并不是!同 Readable 一样,它也得覆写某个方法来监听操作。下面是创建一个 Writable 让用户往里面写入内容,并监听用户到底写了什么的例子(基于 babel-node):

import stream from 'stream';

var w = new stream.Writable;

w._write = (buffer, enc, next) => {
 console.log(buffer + '');
 next(); // 触发「写入完成」
};

w.on('finish', () => {
 console.log('finish');
});
 
void function callee(i) {
 if(i < 10) {
  w.write(i + '', 'utf-8', () => {
   // 写入完成
  });
 } else {
  w.end();
 }
 setTimeout(callee, 10, i + 1);
}(0);

同 Readable 的 _read 一样,如果上面的 _write 没有被覆写将抛出异常:

Error: not implemented
  at Writable._write (_stream_writable.js:430:6)
  at doWrite (_stream_writable.js:301:12)

另外,write 被设计为一个异步方法,它又第三个参数可以传入完成的回调。而所谓完成就是在实现函数 _write 中,next 参数被调用。把 write 设计成异步是有原因的,如果它是同步执行,那么当我们需要在 _write 方法中处理一些异步事务时就可能产生顺序出错。比如一个磁盘文件的写操作就是一个异步的,如果我们写文件无视这个异步,那么假如上一个写操作被堵塞还没完成,当前的写操作可能会先执行。所以我们应该在 _write 中合理地调用 next(必须调用,否则将陷入等待,无法继续写)。

最后,当数据写完成后会触发 finish 事件,这就意味着 end 方法被用户调用了。如果其间做的是写文件的操作,此时就应该关闭文件。

Javascript 相关文章推荐
javascript dom代码应用 简单的相册[firefox only]
Jun 12 Javascript
jquery ui dialog ie8出现滚动条的解决方法
Dec 06 Javascript
JavaScript面向对象设计二 构造函数模式
Dec 20 Javascript
分享两个手机访问pc网站自动跳转手机端网站代码
Dec 24 Javascript
js实现鼠标悬停图片上时滚动文字说明的方法
Feb 17 Javascript
jQuery实现按键盘方向键翻页特效
Mar 18 Javascript
js利用appendChild对标签进行排序的实现方法
Oct 16 Javascript
原生JS实现匀速图片轮播动画
Oct 18 Javascript
详解用vue.js和laravel实现微信授权登陆
Jun 23 Javascript
vue 地区选择器v-distpicker的常用功能
Jul 23 Javascript
JS实现吸顶特效
Jan 08 Javascript
微信小程序实现菜单左右联动
May 19 Javascript
浅谈Javascript数组索引
Jul 29 #Javascript
JQ实现新浪游戏首页幻灯片
Jul 29 #Javascript
JavaScript中几种排序算法的简单实现
Jul 29 #Javascript
详解JavaScript中数组的相关知识
Jul 29 #Javascript
javascript+canvas实现刮刮卡抽奖效果
Jul 29 #Javascript
js实现登陆遮罩效果的方法
Jul 28 #Javascript
怎么通过onclick事件获取js函数返回值(代码少)
Jul 28 #Javascript
You might like
30个php操作redis常用方法代码例子
2014/07/05 PHP
基于php实现七牛抓取远程图片
2015/12/01 PHP
简单PHP会话(session)说明介绍
2016/08/21 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
jqueryUI里拖拽排序示例分析
2015/02/26 Javascript
nodejs中实现sleep功能实例
2015/03/24 NodeJs
jquery判断密码强度的验证代码
2020/04/22 Javascript
全面了解JavaScript的数据类型转换
2016/07/01 Javascript
浅谈angular.js跨域post解决方案
2017/08/30 Javascript
angular基于ng-alain定义自己的select组件示例
2018/02/23 Javascript
JS判断两个数组或对象是否相同的方法示例
2019/02/28 Javascript
微信小程序实现带参数的分享功能(两种方法)
2019/05/17 Javascript
解决vue addRoutes不生效问题
2020/08/04 Javascript
JavaScript日期库date-fn.js使用方法解析
2020/09/09 Javascript
[06:33]DOTA2亚洲邀请赛小组赛第二日 TOP10精彩集锦
2015/01/31 DOTA
[51:44]2018DOTA2亚洲邀请赛 4.3 突围赛 Optic vs iG 第二场
2018/04/04 DOTA
[01:08:56]DOTA2-DPC中国联赛 正赛 Magma vs LBZS BO3 第一场 2月7日
2021/03/11 DOTA
Python Tkinter简单布局实例教程
2014/09/03 Python
详解Pytorch 使用Pytorch拟合多项式(多项式回归)
2018/05/24 Python
解决Mac下首次安装pycharm无project interpreter的问题
2018/10/29 Python
pyqt5 获取显示器的分辨率的方法
2019/06/18 Python
Python如何调用JS文件中的函数
2019/08/16 Python
tensorflow2.0保存和恢复模型3种方法
2020/02/03 Python
logging level级别介绍
2020/02/21 Python
tensorflow中tf.reduce_mean函数的使用
2020/04/19 Python
Python异常处理机制结构实例解析
2020/07/23 Python
python两种获取剪贴板内容的方法
2020/11/06 Python
Html5实现移动端、PC端 刮刮卡效果
2016/06/30 HTML / CSS
HTML5+CSS3:3D展示商品信息示例
2017/01/03 HTML / CSS
Joie官方网上商店:购买服装和女装配饰
2018/06/05 全球购物
金融专业大学生职业生涯规划范文
2014/01/16 职场文书
小学五年级语文上册教学计划
2015/01/22 职场文书
高一军训决心书
2015/02/05 职场文书
中班下学期个人总结
2015/02/12 职场文书
2015年物流客服工作总结
2015/07/27 职场文书
导游词之西湖雷峰塔
2019/09/18 职场文书