在脚本中阻塞节点
我正在使用Node.js编写在服务器上运行的系统脚本。 由于Node的asynchronous特性,在数据库调用有机会完成之前我的脚本正在退出,而且没有任何数据写入数据库。
我使用Mongoose作为ORM并与MongoDB交谈,如果这有什么区别的话。 Node.js为此提供了SYNCHRONOUS方法调用,例如: https : //nodejs.org/api/child_process.html
我想我的问题是:
1)mongoose是否提供阻止的方法,这样我的脚本过程就可以等待数据库调用返回?
2)如果不是,除了类似的东西外,还有其他的方法我应该考虑:
(function wait () { if (!SOME_EXIT_CONDITION) setTimeout(wait, 1000); })();
3)节点不是编写脚本的最佳工具吗? 我喜欢Web应用程序开发的节点,并且可以编写嵌套的callback函数或整天使用promise。 但是作为一种脚本语言呢?
编辑———————————————–
以下是脚本的一个简单示例,以更清晰地说明情况:
#!/usr/bin/env node # Please note the above that this is a bash script var schema = mongoose.Schema({ // ... attributes ... }); var model = new (mongoose.model('ModelObject'))(); model['attribute'] = 42; console.log('This gets printed first'); model.save(function(err) { console.log('Nothing in the callback gets printed because callback is never called'); if(err) { // Can't check for errors because this is never reached console.log('This never gets printed to the screen'); console.log('And consequently nothing is ever saved to mongo'); } else { console.log('This never gets printed either'); } }); console.log('This gets printed second');
如果你的模型没有得到保存,就会出现Mongo错误。 遵循MongoDB约定,你必须检查错误:
model.save(function(error, savedItem) { if(error) { // nothing is saved } });
否则,你有没有考虑使用承诺? 它有助于链接事件和更简单的error handling。
Promise = require('bluebird'); Promise.promisifyAll(mongoose.Query.base); model.saveAsync().then(function(savedItem) { // saved }) .catch(function(error) { // handle error });
我认为你正在寻找这个,检查下面,如果这有助于你。
var mongoose = require('mongoose'), model1 = mongoose.model('model1'), model2 = mongoose.model('model2'); model1.findOne({"type" : 'Active'}, function err(err, catConfig) { if(!err.error){ //This will execute once above DB call is done! model2.findOne(condition).remove(function(err, gAnalysis) { //Lines of code that you want to execute after second DB call }); } });
我没有看到你打开一个连接到数据库,所以大概保存一个模型实例什么都不做,甚至没有调用一个错误的callback…
我已经testing了下面的例子:
test.js :
var mongoose = require('mongoose'); var kittySchema = mongoose.Schema({ name: String }); var Kitten = mongoose.model('Kitten', kittySchema); mongoose.connect('mongodb://localhost:27017/test', function (err) { if (err) throw err; var silence = new Kitten({ name: 'Silence' }); silence.save(function (err, saved) { if (err) throw err; console.log('Kitty Silence is saved!'); mongoose.disconnect(function (err) { if (err) throw err; console.log('done...'); }); }); });
运行node test.js
输出到控制台:
Kitty Silence is saved! done...
并检查我的本地testing数据库显示,确实保存了沉默 。