我有一个工具,其基本思路如下:
//get a bunch of couchdb databases. this is an array
const jsonFile = require('jsonfile');
let dbList = getDbList();
const filePath = 'some/path/to/file';
const changesObject = {};
//iterate the db list. do asynchronous stuff on each iteration
dbList.forEach(function(db){
let merchantDb = nano.use(db);
//get some changes from the database. validate inside callback
merchantDb.get("_changes", function(err,changes){
validateChanges(changes);
changesObject['db'] = changes.someAttribute;
//write changes to file
jsonFile.writeFile(filePath, changesObject, function (err) {
if (err) {
logger.error("Unable to write to file: ");
}
});
})
const validateChanges = function(changes) {
if (!validateLogic(changes) sendAlertMail();
}
为了提高性能,迭代不是同步完成的。因此,可以“并行”运行多个迭代。我的问题是这会导致任何数据不一致和/或文件写入过程出现任何问题吗?
编辑: 每次迭代都会写入相同的文件。
编辑:2 更改存储为具有键值对的 JSON 对象。键是数据库名称。
最佳答案
如果您真的在写入一个单个 文件,而您看起来确实是(尽管很难确定),那么不;你有一个竞争条件,其中多个回调可能会同时尝试写入同一个文件(请记住,I/O 不会在 Node 中的 JavaScript 线程上完成,除非你使用 *Sync
函数),这最多意味着最后一个获胜,最坏的情况是由于重叠导致 I/O 错误。
如果您要为每个 db
写入单独的文件,则前提是 validateChanges
、validateLogic
之间没有串扰(共享状态) >、sendAlertMail
等,应该没问题。
仅供引用:它将启动任务(作业)获取更改,然后将其写出;调用 get
的回调将在所有这些作业都排队后才会运行。
您正在循环中创建闭包,但您这样做的方式没问题,因为您是在 forEach
回调中执行此操作,而且因为您没有使用 db
在 get
回调中(这对于 forEach
回调来说很好,但对于您可能循环数组的其他一些方式则不行)。 this question's answers 中有关这方面的详细信息如果你有兴趣。
不过,这条线是可疑的:
let merchantDb = nano.use('db');
我怀疑你的意思是(没有引号):
let merchantDb = nano.use(db);
对于它的值(value),从问题的更新和您的各种评论来看,更好的解决方案是不每次单独写出文件。相反,您想收集更改,然后将它们写出来。
您可以像这样使用您正在使用的经典 Node 回调 API 来做到这一点:
let completed = 0;
//iterate the db list. do asynchronous stuff on each iteration
dbList.forEach(function(db) {
let merchantDb = nano.use(db);
//get some changes from the database. validate inside callback
merchantDb.get("_changes", function(err, changes) {
if (err) {
// Deal with the fact there was an error (don't return)
} else {
validateChanges(changes);
changesObject[db] = changes.someAttribute; // <=== NOTE: This line had 'db' rather than db, I assume that was meant to be just db
}
if (++completed === dbList.length) {
// All done, write changes to file
jsonFile.writeFile(filePath, changesObject, function(err) {
if (err) {
logger.error("Unable to write to file: ");
}
});
}
})
});
关于javascript - 异步迭代时的node.js数据一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47532838/