我有一个将(冻结)JSON对象插入MongoDB的函数:
var result = null, OID = null ;
...
var test = dbHandle.collection('TestItems') ;
result = prepareObject() ;
test.insert(result, {w:1}, function(err, item) {
if (err) throw err ;
OID = ObjectID(item[0]._id) ;
test.update({_id: OID}, {$set: { userName: socket.userName, state: 'Ready'} }, {w:1}, function( err ) {
if (err) throw err ;
test.findOne({ _id: OID }, function (err, loaded) {
if (err) throw err ;
socket.emit('newData', { data: loaded }) ;
});
}) ;
}) ;
此代码可以正常运行。但是,在我的代码中,我需要使用OID和结果对象,但它们总是未定义的。我知道我一定做错了但我不知道是什么。我的背景是用C ++编写的,我的方法对我有意义,但这是我第一次尝试使用JavaScript / NodeJS / MongoDB。如果有人能指出我正确的方向,我将不胜感激。
例如,当我稍后尝试创建一个新对象时:
var myObj = {Title: result.Title, TID: OID, Stuff:'More Stuff Here'} ;
当将此对象插入MongoDB时,Title和TID值都未定义,但我的TestItems集合已正确更新,暗示OID具有值!这是某种形式的范围问题吗?我无法看到声明,作业和使用是如何在同一个闭包中。
答案 0 :(得分:0)
这很可能是异步设计的问题。 你的test.insert函数获得了所谓的“回调”函数作为第三个参数。插入完成后将调用此函数,但test.insert不会阻止执行,因此您可以在调用回调之前执行更多代码。
为了让您更好地了解正在发生的事情,您的脚本按此顺序运行:
您可以做的是将代码放在要使用OID和test.insert的函数中,并从test.insert回调中调用它:
result = prepareObject();
test.insert(result, ..., function(err, item) {
// do stuff, get result objects, OID, etc
// call your onInsertFinish function (pass result and OID to avoid using globals)
onInsertFinish(result, OID);
});
function onInsertFinish(result, OID) {
// do stuff with result and OID
}
希望这有帮助。