这是我参与8月更文挑战的第24天,活动详情查看:8月更文挑战
一点感悟
我发现身边很多朋友,在做 node 开发的时候,如果遇到一个此前没做过的需求,会有两种表现:
- 第一种表现就是问度娘,好一点的问谷歌
- 第二种表现是问别人
首先说问别人,最后可能得到一个思路,但有时候可能也让你更加的模棱两可,因为你此前根本没有对 API 的认知,也没有对实现思路进行基本思考,在这种情况下把别人的思路强加给你,无益于你的需求实现
而直接百度或者谷歌,其实和问别人一样,得到的都是别人的思路,唯一不同点在于,在这个检索过程中,你会进行思考,形成基础的思维。
但我结合自身的经验,发现了一个问题:
通常情况下,在我们拿到某个需求,却完全不知道从何下手的时候,其实我们已经在脑子里检索了一遍,当我们的知识储备没有发现任何能用于实现这个需求的相关知识,就会束手无策。
举个例子:
假设我现在要做一个导出 csv 文件的需求,如果我不知道 node 中 fs 这个文件系统,那我可能直接就懵了,因为在前端我知道
<a download="**" href="..."></a>这种可以用来下载,但是在 node 中没有这种东西啊~所以我就懵了,就不知道怎么办,就只能问百度,然后人家说,fs 可以写文件,这时候我又去查 fs 这个 API,然后在 csdn、思否上各种看,嗯,好像明白了,其实这本质上就是一个 cv 的过程,你实现了这个需求以后,美滋滋的下班了
那么这时候你在路上等公交的时候,你想你这一天完成的需求,你能独立的讲出 fs 它是做什么的吗?它有几个常用的方法呢?都是怎么用的呢?你这工作了一天,学了什么新的东西吗?
所以,真正的问题在于,我的知识面不够广,知识储备的不够深,完完全全照顾不到日常的开发需求了。如果我对 fs 这个文件系统有一点基础的印象或者认知,我就直接去看文档就好了。
言归正传
node 的 fs 文件系统是非常常用的模块,可以用来非常方便的对文件、文件夹进行增删改查读写等操作。
使用 fs 不需要额外的安装,直接引入就可以了,并且 fs 提供了多种引入和使用的方法。
- 基于回调函数的异步
import * as fs from 'fs';
// or
import { unlink } from 'fs';
因为像是文件读写这种操作,都是异步操作,所以才会使用回调函数,并且,node 遵循错误优先的原则,在回调中第一个参数往往是 ERROR 对象,用来在操作异常时捕获异常,如果操作没有异常,则第一个参数为null或者undefined
unlink('./hello.txt', (err) => {
if (err) throw err;
console.log('successfully deleted ./hello.txt');
});
- 基于 promise API 的异步
import * as fs from 'fs/promises';
// or
import { unlink } from 'fs/promises';
promise 的出现使得我们可以以同步的逻辑编写异步代码,很大程度上解决了回调地狱的问题,虽然写法简单,但是 promise API 不能捕获异常,需要借助于try{}catch(){}语句。
try {
await unlink('./hello.text');
console.log('successfully deleted ./hello.text');
} catch (error) {
console.error('there was an error:', error.message);
}
使用 promise API 需要额外的注意:
Promise API 使用底层的 Node.js 线程池在事件循环线程之外执行文件系统操作。 这些操作不是同步的也不是线程安全的。 对同一文件执行多个并发修改时必须小心,否则可能会损坏数据。
- 同步的写法
同步的代码会阻止 Node.js 事件循环和后面的 JavaScript 代码执行,直到同步的操作完成。所以一般情况下谨慎使用或者不用。
import { unlinkSync } from 'fs';
try {
unlinkSync('./hello.text');
console.log('successfully deleted ./hello.text');
} catch (err) {
console.error('there was an error:', error.message);
}
导出 csv
在程序开发中,时常需要将数据导出为 csv,txt,甚至 pdf 等文件,供用户进行数据查看或分享。
下面,让我们用 fs 来实现,如何将数据导出为 csv 文件。
- 新建文件夹 node-csv
- 在文件夹内新建文件 demo.js
- 用编辑器打开,编辑 demo.js
const { promises: { readFile, writeFile, mkdir } } = require('fs');
(async () => {
// 创建模拟数据
let list = []
for (let i = 0; i < 10; i += 1) {
list.push({
id: i,
name: '小明',
age: 18,
address: '北京市海淀区农业科学院',
phone: '13313366789',
})
}
/*
* 生成表头,\ufeff 是防止乱码
* csv中以 `,` 换列,`\n`换行
*/
let title = Object.keys(list[1])
let csvContent = '\ufeff' + title.join(',') + '\n'
// 添加表体
list.forEach((item, index) => {
let c = Object.values(item).join(',') + '\n'
csvContent += c
})
// 生成文件夹存储生成的文件
await mkdir('download')
// 生成csv文件
await writeFile('./download/data.csv', csvContent)
// 生成JOSN
await writeFile('./download/data.json', JSON.stringify(list))
console.log('File generated successfully,open download to check')
})()
保存后在 cmd 或者 terminal 中运行如下命令
node demo
当你看到这样的提示
ExperimentalWarning: The fs.promises API is experimental
File generated successfully,open download to check
就说明我们的生成 csv 成功了,然后 node-csv,接着打开 download 文件夹,查看生成的 csv 和 json 文件即可。
如果想了解 fs 的 promise ,或者如何生成 txt,请点击这里
码字不易,送一个赞可好~~