node.js异步迭代时的数据一致性

时间:2017-11-28 13:31:47

标签: javascript node.js asynchronous concurrency couchdb

我有一个工具的基本想法如下:

//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();
}

为了提高性能,迭代不是同步完成的。因此,可以在&& 39; parallel'中运行多次迭代。我的问题是,这会导致任何数据不一致和/或文件编写过程中的任何问题吗?

修改 每次迭代都会写入相同的文件。

修改:2 更改存储为具有键值对的JSON对象。关键是数据库名称。

1 个答案:

答案 0 :(得分:2)

如果你真的写了一个单个文件,你似乎是这个文件(虽然很难确定),但是没有;你有一个竞争条件,其中多个回调将尝试写入同一个文件,可能同时(记住,除非你使用*Sync,否则I / O不会在Node中的JavaScript线程上完成函数),这最多意味着最后一个获胜,并且最坏的意思是由于重叠而导致的I / O错误。

如果您正在为每个db写入单独的文件,那么在validateChangesvalidateLogic,{之间没有交叉谈话(共享状态) {1}}等,应该没问题。

仅供参考:它将启动任务(作业)获取更改然后将其写出来;调用sendAlertMail的回调将一直运行到以后,当所有这些作业都排队时。

您正在创建环路闭合,但是你的方式'再这样做是好的,一方面是因为你'再在get回调中和,因为你&#39这样做;再未使用{ forEach回调中的{1}}(对于db回调可能没什么问题,但是可能没有其他方法可以循环数组)。如果您有兴趣,可以在this question's answers中详细了解该方面。

但这条线很可疑:

get

我怀疑你的意思(没有引号):

forEach

对于它的价值,它从问题的更新中发出,并且您的各种评论,例如更好的解决方案将每次单独写出文件。相反,您希望收集更改,然后将其写出来。

您可以使用您正在使用的经典Node-callback API执行此操作:

let merchantDb = nano.use('db');