2016-08-26 14 views
6

Obecnie używa węzła 4.3.2 i mongo 2.6. Próbuję uzyskać całą kolekcję (trzy dokumenty obecnie w kolekcji). Kiedy używam tego kodu, napotykam problem.cursor.toArray() zwraca obietnicę zamiast tablicy

function checkUpdateTime(last_updated){ 
    var collection = db.collection(last_updated); 
    collection.insert({a:1}); 
    updateTimes = collection.find({a:1}).toArray(); 
} 
var updateTimes = []; 
checkUpdateTime('last_updated'); 
console.log(updateTimes); 

Kiedy ten kod jest ustawiony, updateTimes jest obietnicą, a nie tablicą, na którą liczyłem. Celem jest edycja tablicy, a następnie wstawienie jej z powrotem do kolekcji. Instrukcja insert działa, ale pobieranie dokumentów po prostu nie działa tak, jak oczekiwałem. Próbowałem kilka wersji tego kodu, ale nie kości.

Zgaduję, że sprowadza się do mnie pytanie, dlaczego obietnica jest zwracana?

kierowca

Odpowiedz

9

MongoDB oferuje dwie opcje do obsługi asynchronicznych operacji:

  • za pośrednictwem wywołania zwrotne, które przejdzie przez dzwoniącego
  • wracając obietnicę rozmówcy

kiedy nie przekazać wywołanie zwrotne, tak jak w twoim przypadku, zwróci obietnicę.

Musisz dokonać wyboru tutaj. Jedną z opcji, których nie możesz wybrać, jest "spraw, aby ten kod działał synchronicznie", ale.

Wolę obietnice

function checkUpdateTime(last_updated){ 
    var collection = db.collection(last_updated); 
    return collection.insert({ a : 1 }) // also async 
        .then(function() { 
        return collection.find({ a : 1 }).toArray(); 
        }); 
} 
checkUpdateTime('last_updated').then(function(updateTimes) { 
    console.log(updateTimes); 
}); 

Można zawsze iść nieco bardziej wyszukane i użyć coś jak Promise.coroutine, które uczynią swój kod wyglądać nieco bardziej synchroniczny (choć nie jest):

const Promise  = require('bluebird'); 
const MongoClient = require('mongodb').MongoClient; 

let checkUpdateTime = Promise.coroutine(function* (db, last_updated){ 
    let collection = db.collection(last_updated); 
    yield collection.insert({ a : 1 }); 
    return yield collection.find({ a : 1 }).toArray(); 
}); 

Promise.coroutine(function *() { 
    let db = yield MongoClient.connect('mongodb://localhost/test'); 
    let updateTimes = yield checkUpdateTime(db, 'foobar'); 
    console.log(updateTimes); 
})(); 

lub async/await, używając Babel:

const MongoClient = require('mongodb').MongoClient; 

async function checkUpdateTime(db, last_updated) { 
    let collection = db.collection(last_updated); 
    await collection.insert({ a : 1 }); 
    return await collection.find({ a : 1 }).toArray(); 
} 

(async function() { 
    let db = await MongoClient.connect('mongodb://localhost/test'); 
    let updateTimes = await checkUpdateTime(db, 'foobar'); 
    console.log(updateTimes); 
})(); 
+0

'" ty nie można wybrać "'. On może. Z 'async/await'. –

+0

@vp_arth nadal, to nie sprawi, że będzie synchroniczne (wskazówka jest w nazwie, "async" ;-). Może jednak to lubić, dlatego dodałem to jako przykład: D – robertklep