在NodeJS中,异步读取文件有三种方式:
1. 通过回调函数
2. 使用Promise
3. 使用ES7提供的async/await语法
这里总结和实例演示了NodeJS异步读取文件的三种方式,便于说明他们各自的优缺点,便于学习理解和记忆。
目标文件格式
// a.json
{
"next": "b.json",
"msg": "This is a!"
}
// b.json
{
"next": "c.json",
"msg": "This is b!"
}
// c.json
{
"next": null,
"msg": "This is c!"
}
第一种方式:使用传统的回调函数。采用这种方法,将回调函数传入NodeJS的fs.readFile()
方法中,回调函数接收两个参数err
和data
,用于保存出错信息和读取成功后的文件数据。采用这种方式的最大弊端,在于回调函数嵌套所形成的回调地狱,不便于代码的阅读和维护。
// Node使用回调函数 读取文件
const fs = require('fs')
const path = require('path')
const getFileData = (filename, callback) => {
const fileFullName = path.resolve(__dirname, filename)
fs.readFile(fileFullName, (err, data) => {
if (err) {
console.error(err)
return
}
callback(
JSON.parse(data)
)
})
}
getFileData('a.json', data => {
console.log(data)
getFileData(data.next, data => {
console.log(data)
getFileData(data.next, data => {
console.log(data)
})
})
})
/**
{ next: 'b.json', msg: 'This is a!' }
{ next: 'c.json', msg: 'This is b!' }
{ next: null, msg: 'This is c!' }
*/
第二种方式:使用Promise。使用Promise方法,解决了回调函数嵌套所形成的回调地狱问题。在一个Promise中返回另一个Promise,通过链式调用拆解回调函数嵌套嵌套。
// NodeJS 使用Promise读取文件
const fs = require('fs')
const path = require('path')
const getFileData = function (fileName) {
let promise = new Promise((resolve, reject) => {
let fileFullName = path.resolve(__dirname, fileName)
fs.readFile(fileFullName, (err, data) => {
if (err) {
reject(err)
return
}
resolve(JSON.parse(data))
})
})
return promise
}
getFileData('a.json').then(data => {
let fileFullName = path.resolve(__dirname, data.next)
console.log(data)
return getFileData(fileFullName)
}).then(data => {
let fileFullName = path.resolve(__dirname, data.next)
console.log(data)
return getFileData(fileFullName)
}).then(data => {
console.log(data)
})
/**
{ next: 'b.json', msg: 'This is a!' }
{ next: 'c.json', msg: 'This is b!' }
{ next: null, msg: 'This is c!' }
*/
第三种方式:使用ES7提供的async/await
语法,异步读取文件内容。async/await
函数必须成对使用(await
必须出现在async
函数中),关键词await
可以让JavaScript进行等待,直到一个promise
执行并返回它的结果,JavaScript才会继续往下执行。
// NodeJS 使用async/await 读取文件数据
const fs = require('fs')
const path = require('path')
async function getFileData(filename) {
if (filename) {
let fileFullName = path.resolve(__dirname, filename)
let filePromise = new Promise((resolve, reject) => {
fs.readFile(fileFullName, (err, data) => {
if (err) {
reject(err)
return
}
resolve(JSON.parse(data))
})
})
let fileData = await filePromise
console.log(fileData)
arguments.callee(fileData.next)
}
}
let fileDataA = getFileData('a.json')
/**
{ next: 'b.json', msg: 'This is a!' }
{ next: 'c.json', msg: 'This is b!' }
{ next: null, msg: 'This is c!' }
*/
这里演示了NodeJS异步读取文件的三种方式,以此为契机也总结了在Javascript中,处理异步行为的三种方案。
网友评论