Process.Exit()之后没有在Mongo数据库中写入数据

时间:2014-08-16 20:30:54

标签: node.js mongodb asynchronous mongoose

我正在编写一个node.js脚本,在MongoDB数据库中写入一些来自MySQL数据库的数据。它不是Web应用程序,而是本地脚本(我的MySQL和Mongo都是本地脚本)。

问题是,当写入所有数据时,脚本不会终止。我必须用CTRL + C关闭它。但我的所有数据都写在我的MongoDB数据库中。

我在MongoDB中写入后调用的回调末尾添加了一个“process.exit()”行。该应用终止,但没有数据写入!我不明白为什么。

以下是代码的相关部分

(...)
var req = "SELECT * FROM geometry";

// "connection" is a MySQL connection
connection.query(req, function(err, rows, fields) {
    console.log("number of lines :" + rows.length);
    connection.end();

    if (err) {
        throw err;
    }
    // "Entry" is my model
    for (var i = 0; i < rows.length; i++) {
        Entry.create({
            "code" : rows[i].code,
            "name" : rows[i].name,
            "coords" : rows[i].coords,
            "type" : rows[i].type
        }, function(err, doc){
            if (err) {
                throw (err);
            }
        });
    }

    console.log("end");
    process.exit(); // no data written ! why ?
});
你能帮帮我吗? 提前谢谢。

1 个答案:

答案 0 :(得分:2)

问题是你过早地终止了你的过程。您不是在等mongoose实际将任何文档发送到MongoDB。以下是如何正确执行此操作的一些示例。

NB 请先,read this question了解为什么没有写入数据,然后阅读我的回答,了解如何处理 EM>


使用promises和when.js模块

首先,我们应该要求when模块(或任何其他基于承诺的控制流模块,例如Qbluebird)。

when = require('when');

然后我们可以用它来简化我们的代码:

promises = rows.map(function(row) {
  return Entry.create(row);
})
when.all(promises).otherwise(console.error).ensure(function() {
  process.exit()
})

或使用when.map

when.map(rows, function(row) {
  return Entry.create(row);
}).otherwise(console.error).ensure(function() {
  process.exit()
})

N.B。此解决方案可能会染成猫鼬build-in promises support


使用async.js模块

async.js是node.js的基于回调的控制流模块:

async = require('async');

但它几乎和承诺一样强大:

async.map(roes, function(row, next) {
  Entry.create(row, next);
}, function(err){
  if (err) throw (err);
  process.exit();
});

使用纯JavaScript

但是我们可以使用基于纯回调的JavaScript实现相同的结果:

var pending = 0;
rows.forEach(function(row) {
  pending++;
  Entry.create(row, function(err) {
    if (err) throw (err);
    if (--pending === 0) process.exit();
  });
});

关于mongoose

的说明

Bu默认mongoose使用strict mode,所以我只需要调用

Entry.create(row);

知道mongoose将删除row架构中不存在的Entry的任何属性。


关于异步代码和控制流模块的注意事项

控制流模块(promises,async.js等)可以帮助您处理异步代码,但是如果您是node.js和异步编程的新手,我建议您从纯JS方法开始,以便了解节点.js更好。那么采用一些控制流解决方案是安全的。

你还应该注意,promises为你的异步代码提供了一个巨大的抽象层,有很多语法糖,而像async.js这样的基于回调的模块只提供了一点点。

因此,在我看来,掌握node.js的最佳方法如下:

Pure JS -> callback-based modules (async.js) -> promises

最新的node.js 0.11.x(--harmony标志)也支持generators,提供了另一种处理异步代码的方法。