在Node中组织此过程的正确方法



我需要一些关于如何构建这个函数的建议,因为目前由于节点是异步的,它没有以正确的顺序发生

这是我想要达到的流程;我不需要代码本身的帮助,而是需要实现最终结果的顺序以及如何使其高效的任何建议

  1. 节点路由GET请求到我的控制器
  2. 控制器读取本地系统上的。csv文件,并使用fs模块打开读流
  3. 然后使用csv-parse模块将其逐行转换为数组(许多100,000行)
  4. 启动try/catch块
  5. 从csv的当前行,取一个值,并尝试在MongoDB
  6. 中找到它
  7. 如果找到,取ID并将CSV中的行和此ID作为外部ID存储在单独的数据库
  8. 如果没有找到,在DB中创建一个条目并获取新的ID,然后执行6。
  9. 打印出正在处理的行号到终端(理想情况下,在某些时候,我希望能够将此值发送到页面,并在行完成时像进度条一样更新)

这是我目前使用的一小部分代码结构;

const fs = require('fs');
const parse = require('csv-parse');
function addDataOne(req, id) {
const modelOneInstance = new InstanceOne({ ...code });
const resultOne = modelOneInstance.save();
return resultOne;
}
function addDataTwo(req, id) {
const modelTwoInstance = new InstanceTwo({ ...code });
const resultTwo = modelTwoInstance.save();
return resultTwo;
}
exports.add_data = (req, res) => {
const fileSys = 'public/data/';
const parsedData = [];
let i = 0;
fs.createReadStream(`${fileSys}${req.query.file}`)
.pipe(parse({}))
.on('data', (dataRow) => {
let RowObj = {
one: dataRow[0],
two: dataRow[1],
three: dataRow[2],
etc,
etc
};
try {
ModelOne.find(
{ propertyone: RowObj.one, propertytwo: RowObj.two },
'_id, foreign_id'
).exec((err, searchProp) => {
if (err) {
console.log(err);
} else {
if (searchProp.length > 1) {
console.log('too many returned from find function');
}
if (searchProp.length === 1) {
addDataOne(RowObj, searchProp[0]).then((result) => {
searchProp[0].foreign_id.push(result._id);
searchProp[0].save();
});
}
if (searchProp.length === 0) {
let resultAddProp = null;
addDataTwo(RowObj).then((result) => {
resultAddProp = result;
addDataOne(req, resultAddProp._id).then((result) => {
resultAddProp.foreign_id.push(result._id);
resultAddProp.save();
});
});
}
}
});
} catch (error) {
console.log(error);
}
i++;
let iString = i.toString();
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write(iString);
})
.on('end', () => {
res.send('added');
});
};

我试图使函数使用async/await,但它似乎与fs冲突。openReadStream或csv解析功能,可能是由于我的经验不足和缺乏正确使用的代码…

我很感激这是一个关于代码基础的很长的问题,但是只要一些关于如何进行的提示/建议/指针就会很感激。当数据通过邮差的post请求一次发送一个时,我让它工作,但无法实现下一阶段,即从包含许多记录的csv文件中读取

首先,您可以在一个查询中进行以下检查:

if (searchProp.length === 1) {if (searchProp.length === 0) {

在mongodb findOneAndUpdate查询中使用upsert选项来更新或upsert。

其次,不要在主线程中这样做。使用队列机制,效率会高得多。我个人使用的队列是Bull Queue。

https://github.com/OptimalBits/bull基本用法

这还提供了显示进度所需的功能。

同样关于使用Async Await与读流,很多例子可以在网上找到,如:https://humanwhocodes.com/snippets/2019/05/nodejs-read-stream-promise/

最新更新