前言
之前配置 webpack 的时候,使用了一个插件 progress-bar-webpack-plugin, 功能很简单,就是在打包的时候显示一个骚气的进度条,使用如下
1 | // webpack.config.js |

作为 前后左右端配置工程师 2.0, 今天就尝试用 Node.js 实现一个类似的进度条的功能,我们这里稍微丰富一下,模拟这样一个场景:小李取钱,然后出现正在取钱中的 进度条,最后提示取钱成功
标准输入与输出流
在 Node.js 中,标准的输入输出流分别为:
- 输入流
- 输出流
- 错误流
而流又分为:
- 可读流 (Readable)
- 可写流 (Writable)
- 双工流 (Duplex)
- 转换流 (Transform)
其中双工流和转换流都是可读可写的。
输入流 (Readable)
1 | process.stdin; |
输出流 (Writable)
1 | process.stdout; |
错误流 (Writable)
1 | process.stderr; |
想实现进度条在命令行中显示,我们需要用到输出流和输入流,前端的老朋友 console.log 其实就是对标准输出的封装
1 | const { format } = require('util'); |

小李取钱
小李来到银行的自动取款机取钱,取款机询问他要取多少:

要实现 询问 这个功能,我们需要借助一个原生的 Node.js 模块 readline , 它帮助我们从 可读流 中 一行一行的读取数据
1 | const readline = require('readline'); |

接下来就是取钱的过程,我们需要显示一个取钱中的进度条,首先实现一个 printProgress 函数,向 process.stdout 标准中打印进度条
1 | const printProgress = (index) => { |
同时增加 getMoney 函数用来接收小李输入的金额,printProgress 会在他按下回车的时候执行
1 | const getMoney = (money) => { |

提示信息有了,由于银行资金比较紧张,还没有实现加载中的动画,没那味,别着急,我们来实现动画
加载动画
前端对于动画肯定不陌生,方式多种多样,有
- css3 animation
- setInterval
- requestAnimationFrame
- canvas
由于是 Node.js 环境,这里我们只能使用 setInterval 来实现,略微调整一下 getMoney 函数,加入定时器,通过一个自增的 index 的来表示提取的进度
1 | const getMoney = (answer) => { |

“取他个香蕉棒棒槌”, 小李在取款机旁骂道,原来是因为虽然一直在输出,但是没有清空之前的内容,显示效果不理想。
清空标准输出
在 canvas 图形绘制时,我们可以通过 clearRect() 方法不断的清除画布实现动画的绘制,而在命令行中,我们可以使用 readline.clearScreenDown() 来帮助我们清空标准输出
1 | // 将光标移动到 标准输出 (坐标 0,0 ) 的位置 |
修改 printProgress 函数,每次打印前清空即可
1 | const limit = 20; // 模拟提取时长 |

一个小时过去了,取款机还在提示 提取中, 原来是忘了写停止动画了,赶紧加上
1 | const print = (money, index) => { |

最后,我们为了更加逼真,在进度条的前面加上一个百分比
1 | const printProgress = (index) => { |

完整代码如下:
1 | const readline = require('readline'); |
终于,小李取到了他这个月的工资,他回到工地继续那美滋滋的搬砖生活。
完。
