如何使用 Node fs 构建异步流
How to structure async flow using Node fs
我无法让许多异步操作的流程正确进行。正如我下面的代码所示,outside readFile
首先打印到控制台,然后 names
和 years
接下来打印,最后 in readFile
,当我想要的时候整个 readFile
/forEach
处理之前发生。
const fs = require('fs')
const names = {}
const years = {}
fs.readdir('./namesData', (err, files) => {
files.forEach(file => {
var year = file.substr(3, 4)
var yearObj = {}
fs.readFile(`./namesData/${file}`, 'utf8', (err, data) => {
console.log('in readFile')
if (err) throw new Error(err)
var arr = data.split('\n')
arr.forEach(record => {
var recordArray = record.trim().split(',')
var name = recordArray[0]
var gender = recordArray[1]
var score = recordArray[2]
// populate 'names' object
var nameObj = {year: year, gender: gender, score: score}
if (names.hasOwnProperty(name)) {
names[name].push(nameObj)
} else {
names[name] = [nameObj]
}
// populate 'years' object & add to yearObj and then years object
var yearNameObj = {gender: gender, score: score}
if (yearObj.hasOwnProperty(name)) {
yearObj[name].push(yearNameObj)
} else {
yearObj[name] = [yearNameObj]
}
})
})
console.log('outside readFile')
years[year] = yearObj
})
console.log(names)
console.log(years)
})
我试过这种方法。似乎可以满足您在循环后打印 names
、years
的需要。
'use strict';
let _ = require('lodash');
const fs = require('fs');
function readFile(file) {
try {
console.log('in readFile');
return fs.readFileSync(`./namesData/${file}`, 'utf-8');
} catch (err) {
console.log('err ', err.stack);
return '';
}
}
fs.readdir('./namesData', (err, files) => {
let details = _.map(files, (file) => {
let data = readFile(file);
let year = file.substr(3, 4);
return _.map(data.split('\n'), (row) => {
if (_.isEmpty(row)) {
return;
}
let words = row.trim().split(',');
return {
year: year,
name: words[0],
gender: words[1],
score: words[2]
};
});
});
console.log('names', _.groupBy(details, 'name'));
console.log('years', _.groupBy(details, 'year'));
});
使用硬编码 details
数组进行测试
let details = [{
year: 1998,
name: 'A',
gender: 'M',
score: 20
}, {
year: 1998,
name: 'B',
gender: 'M',
score: 21
}, {
year: 1999,
name: 'A',
gender: 'M',
score: 100
}, {
year: 1999,
name: 'A',
gender: 'M',
score: 80
}];
我无法让许多异步操作的流程正确进行。正如我下面的代码所示,outside readFile
首先打印到控制台,然后 names
和 years
接下来打印,最后 in readFile
,当我想要的时候整个 readFile
/forEach
处理之前发生。
const fs = require('fs')
const names = {}
const years = {}
fs.readdir('./namesData', (err, files) => {
files.forEach(file => {
var year = file.substr(3, 4)
var yearObj = {}
fs.readFile(`./namesData/${file}`, 'utf8', (err, data) => {
console.log('in readFile')
if (err) throw new Error(err)
var arr = data.split('\n')
arr.forEach(record => {
var recordArray = record.trim().split(',')
var name = recordArray[0]
var gender = recordArray[1]
var score = recordArray[2]
// populate 'names' object
var nameObj = {year: year, gender: gender, score: score}
if (names.hasOwnProperty(name)) {
names[name].push(nameObj)
} else {
names[name] = [nameObj]
}
// populate 'years' object & add to yearObj and then years object
var yearNameObj = {gender: gender, score: score}
if (yearObj.hasOwnProperty(name)) {
yearObj[name].push(yearNameObj)
} else {
yearObj[name] = [yearNameObj]
}
})
})
console.log('outside readFile')
years[year] = yearObj
})
console.log(names)
console.log(years)
})
我试过这种方法。似乎可以满足您在循环后打印 names
、years
的需要。
'use strict';
let _ = require('lodash');
const fs = require('fs');
function readFile(file) {
try {
console.log('in readFile');
return fs.readFileSync(`./namesData/${file}`, 'utf-8');
} catch (err) {
console.log('err ', err.stack);
return '';
}
}
fs.readdir('./namesData', (err, files) => {
let details = _.map(files, (file) => {
let data = readFile(file);
let year = file.substr(3, 4);
return _.map(data.split('\n'), (row) => {
if (_.isEmpty(row)) {
return;
}
let words = row.trim().split(',');
return {
year: year,
name: words[0],
gender: words[1],
score: words[2]
};
});
});
console.log('names', _.groupBy(details, 'name'));
console.log('years', _.groupBy(details, 'year'));
});
使用硬编码 details
数组进行测试
let details = [{
year: 1998,
name: 'A',
gender: 'M',
score: 20
}, {
year: 1998,
name: 'B',
gender: 'M',
score: 21
}, {
year: 1999,
name: 'A',
gender: 'M',
score: 100
}, {
year: 1999,
name: 'A',
gender: 'M',
score: 80
}];