node.js

时间:2015-04-30 03:10:38

标签: node.js

我是节点中级的初学者。我试图清楚地知道node.js对顺序作业有多好。我必须编写一个迁移脚本,它从数据库A的10个表中获取所有数据,然后将其发布到另一组10个数据库表中。我们需要将插入或读取失败记录到单独的日志文件中。

其他细节

  1. 插入或读取对表没有任何依赖关系。(我只需要确保在插入B中的相应表之前,我从数据库A中读取数据的特定表)
  2. 数据库B是一个缓慢的系统,在超出一定限度的巨大并行请求下可能会失败。因此最好在表格之后插入数据表。
  3. 现在我正在尝试查看节点是否适合这项工作。我知道我们可以通过嵌套回调或异步模块进行串行执行。

    但即使使用异步模块(系列和eachSeries方法),我是否可以保证表一个接一个地迁移,并且对于特定能够一行接一个地插入的行?并且一个表的迁移错误会影响另一个吗?

2 个答案:

答案 0 :(得分:0)

我最近必须做一些非常类似的事情,两个巨大的查询无法并行运行,并且能够使用promises做到这一点。如果你想要的话,这个错误只会影响其他表的迁移,但是如果你的用例适用的话,你可以坚持下去。

这里有一些众所周知的承诺库,你可以用来设置这样的东西。只要每个工作都返回一个承诺,只有在履行承诺后才开始下一个承诺。

Q Promise Library

Bluebird Promises

编辑:这是我的代码在我的超级简单顺序数据库副本中的样子。

replicateDB('fails', FailModel)
  .then(function (message) {
    replicateDB('encodes', EncodeModel);
  },
  function (err) {
    console.log(err);
  })
  .then(function (message) {
    console.log(message);
  },
  function (err) {
    console.log(err);
  })

我使用了Q,因为它很容易添加到我现有的代码中,只需要将以下内容添加到我拥有的replicateDB函数中

var deferred = Q.defer();
...

//If replication failed
deferred.reject(err);
...

//If replication succeeded
deferred.resolve('success in  ' + dbname);

答案 1 :(得分:0)

可以使用async的eachSeries来完成,正如您自己提到的那样。虽然路上有一个凹凸;如果其中一个迭代回调错误,async将停止整个循环。

说你有这个:

var queries = [...]; // Imagine some actual queries

async.eachSeries(queries, function(query, callback) {
    db.query(query, callback); // Do your database thing
}, function handleQueriesCompleted(error) {
    if (error) {
        return console.error(error);
    }
    console.log('Completed!');
});

正如您所知,每个系列只在前一个迭代完成后才开始下一次迭代(即已调用其回调)。

现在说queries包含五个实际查询,前三个成功完成,但第四个产生错误(来自数据库)。现在永远不会执行第五个查询,因为第四次迭代传递了一个错误。

您可以通过包装db.query()调用来缓解此问题,并且只将错误写入日志,而不将错误传递给回调,如下所示:

async.eachSeries(queries, function(query, callback) {
    db.query(query, function(error) {
        if (error) {
             console.error(error);
        }
        callback(null);
    });
}, function handleQueriesComplete(error) { ... } );