2015-07-30 2 views
0

Я пытаюсь написать асинхронную функцию, чтобы дать мне случайный документ из коллекции mongodb.Как переписать асинхронную функцию (node.js, monk)

var getRandDoc = function(){ 
    var db = monk('localhost/data'); 
    var coll = db.get('coll'); 

    coll.count({}, function(err, count){ 
     if (err) console.log(err); 
     else { 
      coll.find({}, {limit:-1, skip:randomNum(0, count)}, function(err, out){ 
       if (err) console.log(err); 
       else{ 
        db.close(); 
        return out[0]['name']; 
       } 
      }); 
     } 
    }); 
} 

В другом файле, я называю эту функцию с чем-то вроде:

console.log(test.getRandDoc()); 

И я получаю undefined

Что я делаю не так и как это исправить?

+0

Что происходит не так? Вы получаете сообщения об ошибках? – azium

+0

Возвращает undefined. Я забыл упомянуть об этом, но отредактировал его. – user3642365

ответ

4

Это обычная путаница обратного вызова узла. Если вы не хотите использовать обещания, getRandDoc() должен принять обратный вызов, а затем вызвать его с результатами в методе coll.find (...). Так что-то вроде этого:

var getRandDoc = function(cb){ 
    var db = monk('localhost/data'); 
    var coll = db.get('coll'); 

    coll.count({}, function(err, count){ 
     if (err) console.log(err); 
     else { 
      coll.find({}, {limit:-1, skip:randomNum(0, count)}, function(err, out){ 
       if (err) return cb(err) 
       else{ 
        db.close(); 
        return cb(null, out[0]['name']); 
       } 
      }); 
     } 
    }); 
} 

Вы, вероятно, хотите передать обратно эту ошибку тоже, так что:

test.getRandDoc(function(err, name){ 
}); 

базирующаяся версия обещания будет выглядеть примерно так:

var getRandDoc = function(){ 
    var db = monk('localhost/data'); 
    var coll = db.get('coll'); 
    var deferred = Q.defer(); 

    coll.count({}, function(err, count){ 
     if (err) deferred.reject(err); 
     else { 
      coll.find({}, {limit:-1, skip:randomNum(0, count)}, function(err, out){ 

       if (err) deferred.reject(err); 
       else{ 
        db.close(); 
        deferred.resolve((out[0]['name']); 
       } 
      }); 
     } 
    }); 

    return deferred.promise; 
    } 

Но это все равно не даст вам прямого назначения переменной. Вы назовёте это примерно так:

Добро пожаловать в узел!

+0

Спасибо за ответ. Это то, что я сделал для отладки, но теперь мне нужно назначить вывод этой функции переменной. 'var rand = getRandDoc()'. Как мне это сделать? – user3642365

+0

Вы не получите версию, которая выполняет простое назначение переменных, но вы можете использовать обещание. Добро пожаловать в узел :)! Я приведу пример. –

+0

Возможно, вы можете отправить пользовательское событие в внешний и внешний файл и связать его с getRandDoc! – Beauceron

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