- 我们有时候会有这样的需求:
如逐行读取某txt里的内容,并且每读取一行,执行一个异步事件,等异步事件执行完后,再读取下一行
。
- 先看使用node提供的
readline
的常用方式是否可以实现我们的需求
import * as fs from 'fs'
import * as readline from 'readline'
async function index() {
// 生成要读取文件的 interface
const file_interface = readline.createInterface({
input: fs.createReadStream('/Users/lusun/Downloads/test.txt')
})
let line_num = 1
// 异步方式,读取每一行的内容
file_interface.on('line', async (input) => {
console.log(line_num++, input)
await pendingTest()
})
}
index();
// 模拟一个耗时 5 秒的异步事件
function pendingTest(){
return new Promise(resolve=>{
setTimeout(()=>{
console.log('等待5秒')
resolve();
},5000)
})
}
/* >>> 控制台数据结果
1 <淘宝>
2 [电器]
3 电视
4 冰箱
5 洗衣机
6 [家具]
7 沙发
8 床
9 凳子
等待5秒
等待5秒
等待5秒
等待5秒
等待5秒
等待5秒
等待5秒
等待5秒
等待5秒
*/
- 我们可以看到输出的结果,其实并不是我们想要的,我们需要每读取一行,然后执行异步事件(如上5秒事件),等待异步事件执行完,再读取下一行
- 要实现上面的需求,
readline
也为我们提供了AsyncIterator
方式,具体就是使用ES9
新增的for await of
(完整代码如下)
import * as fs from 'fs'
import * as readline from 'readline'
async function index() {
// 生成要读取文件的 interface
const file_interface = readline.createInterface({
input: fs.createReadStream('/Users/lusun/Downloads/test.txt')
})
let line_num = 1
// 同步方式,读取每一行的内容
for await (const input of file_interface) {
console.log(line_num++,input)
await pendingTest()
}
}
index();
// 模拟一个耗时 5 秒的异步事件
function pendingTest(){
return new Promise(resolve=>{
setTimeout(()=>{
console.log('等待5秒')
resolve();
},5000)
})
}
/* >>> 控制台数据结果
1 <淘宝>
等待5秒
2 [电器]
等待5秒
3 电视
等待5秒
4 冰箱
等待5秒
5 洗衣机
等待5秒
6 [家具]
等待5秒
7 沙发
等待5秒
8 床
等待5秒
9 凳子
等待5秒
*/