2015-09-08 2 views
4

Я использую Node.js для написания системных сценариев, которые запускаются на сервере. Из-за асинхронного характера Node мой скрипт выходит до того, как вызовы базы данных имеют шанс завершить, и ничто никогда не записывается в базу данных.Блокирующий узел в скрипте

Я использую Mongoose как ORM и разговариваю с MongoDB, если это имеет значение. Node.js предлагает синхронные вызовы методов по этой причине, например: https://nodejs.org/api/child_process.html

Я думаю, мои вопросы:

1) Предлагает ли мангуста способ блокировать таким образом мой процесс сценариев может ждать вызова базы данных в вернуть?

2) Если нет, то есть еще один метод, который я должен рассмотреть другие, чем-то вроде:

(function wait() { 
    if (!SOME_EXIT_CONDITION) setTimeout(wait, 1000); 
})(); 

3) узел не является лучшим инструментом для работы для написания сценариев? Мне нравится узел для разработки веб-приложений, и я могу писать вложенные обратные вызовы или работать с обещаниями в течение всего дня. Но как насчет скриптового языка?

EDIT --------------------------------------------- -

ниже приведен краткий пример сценария для обеспечения большей ясности ситуации:

#!/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'); 
+1

Неясно, в чем проблема. «мой скрипт выходит, прежде чем вызовы базы данных имеют шанс завершить». Можете ли вы подробнее рассказать об этом? Поделитесь своим кодом, который создает проблему и подробно описать ее. – marekful

+0

Метод, который вы описали, совершенно прекрасен, что мешает вам его использовать? – sdgluck

+0

Возможно, метод сохранения поднимается и возникает ошибка, и вы не поймаете/не показываете его – cesarluis

ответ

0

Я думаю, что вы ищете это, проверьте ниже, если это поможет вам.

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 
     }); 
    } 
}); 
+1

Привет, спасибо за ваш ответ. Похоже, что это будет работать при запуске узла как веб-приложения с помощью команды node, но при запуске в качестве сценария внутренний вызов никогда не будет выполнен, потому что система выходит из сценария до того, как обратный вызов будет вызван. Поэтому функция «model2.findOne (условие)» никогда не вызывается. – ossys

+0

@ossys: Способ работы узла заключается в том, что система никогда не выходит, пока есть вызовы, еще не вызванные. – slebetman

1

Если ваша модель не спасена, есть ошибка Mongo. В соответствии с соглашениями MongoDB вы должны проверить наличие ошибок:

model.save(function(error, savedItem) { 
    if(error) { 
    // nothing is saved 
    } 
}); 

В противном случае вы считали, что используете обещания? Это полезно для цепочки событий и упрощения обработки ошибок.

Promise = require('bluebird'); 
Promise.promisifyAll(mongoose.Query.base); 

model.saveAsync().then(function(savedItem) { 
    // saved 
}) 
.catch(function(error) { 
    // handle error 
}); 
+0

благодарю вас за ваш ответ ... однако из-за того, что обратный вызов никогда не выполняется, я не могу проверить наличие ошибок. Сценарий останавливается до вызова callback. Я внес изменения, надеюсь, продемонстрировать немного лучше ситуацию. – ossys

0

Я не вижу вас открыть соединение с базой данных, так предположительно сохранения экземпляра модели ничего не делает, даже не вызывать обратный вызов с ошибкой ...

Я проверил приведенный ниже пример :

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... 

и изучение моей локальной базы данных тест показывает, что Silence действительно спасен.

Смежные вопросы