2016-02-06 10 views
9

Jestem nowicjuszem w węźle i mongo po 15 latach VB6 i MySql. Jestem pewien, że to nie jest to, czego użyje mój końcowy program, ale muszę uzyskać podstawową wiedzę o tym, jak wywołać funkcję w innym module i uzyskać wyniki z powrotem.Node.js, Mongo znajduj i zwróć dane

Chcę, aby moduł miał funkcję otwierania bazy danych, znajdowania w zbiorze i zwracania wyników. Być może zechcę dodać kilka dodatkowych funkcji w tym module dla innych zbiorów. Na razie potrzebuję go maksymalnie prostego, mogę dodać obsługę błędów itp. Później. Byłem na tym przez kilka dni próbując różnych metod, module.exports = {... wokół funkcji i bez niej, .send, zwróć wszystko bez powodzenia. Rozumiem, że jest to asynchronizacja, więc program mógł minąć punkt wyświetlania przed danymi.

Oto, co próbowałem z Mongo z bazą danych db1 z kolekcją col1.

Db1.js 
var MongoClient = require('mongodb').MongoClient; 
module.exports = { 
    FindinCol1 : function funk1(req, res) { 
    MongoClient.connect("mongodb://localhost:27017/db1", function (err,db) { 
      if (err) { 
       return console.dir(err); 
      } 
      var collection = db.collection('col1'); 
      collection.find().toArray(function (err, items) { 
        console.log(items); 
        // res.send(items); 
       } 
      ); 
     }); 
    } 
}; 


app.js 
a=require('./db1'); 
b=a.FindinCol1(); 
console.log(b); 

console.log (pozycje) działa, gdy nazywa "FindinCol1 Ale nie console.log (b) (wraca„niezdefiniowana”), więc ja nie dostaję zwrot lub mam wklejony przez czas to zwroty. Czytałem dziesiątki postów i oglądałem dziesiątki filmów, ale wciąż jestem w tym punkcie. Każda pomoc będzie bardzo ceniona.

Odpowiedz

16

Jak wspomniano w innym odpowiedź, ten kod jest asynchroniczny, nie można po prostu zwrócić żądanej wartości w dół łańcucha wywołań zwrotnych (gniazdo funkcje ed). Musisz odsłonić pewien interfejs, który pozwoli ci zasygnalizować kod wywołujący, gdy uzyskasz żądaną wartość (stąd wywołanie ich lub oddzwanianie).

Istnieje przykład wywołania zwrotnego w innej odpowiedzi, ale jest inna opcja zdecydowanie warta odkrycia: promises.

Zamiast wywoływać funkcję zwrotną z żądanymi wynikami, moduł zwraca obietnicę, która może wprowadzić dwa stany, spełnione lub odrzucone. Kod wywołujący czeka, aż obietnica wejdzie w jeden z tych dwóch stanów, przy czym wywoływana jest odpowiednia funkcja. Moduł wyzwala zmianę stanu przez resolve lub reject. Tak czy inaczej, to jest przykład za pomocą obietnic

Db1.js:

// db1.js 
 
var MongoClient = require('mongodb').MongoClient; 
 
/* 
 
node.js has native support for promises in recent versions. 
 
If you are using an older version there are several libraries available: 
 
bluebird, rsvp, Q. I'll use rsvp here as I'm familiar with it. 
 
*/ 
 
var Promise = require('rsvp').Promise; 
 

 
module.exports = { 
 
    FindinCol1: function() { 
 
    return new Promise(function(resolve, reject) { 
 
     MongoClient.connect('mongodb://localhost:27017/db1', function(err, db) { 
 
     if (err) { 
 
      reject(err); 
 
     } else { 
 
      resolve(db); 
 
     }   
 
     } 
 
    }).then(function(db) { 
 
     return new Promise(function(resolve, reject) { 
 
     var collection = db.collection('col1'); 
 
     
 
     collection.find().toArray(function(err, items) { 
 
      if (err) { 
 
      reject(err); 
 
      } else { 
 
      console.log(items); 
 
      resolve(items); 
 
      }   
 
     }); 
 
     }); 
 
    }); 
 
    } 
 
}; 
 

 

 
// app.js 
 
var db = require('./db1'); 
 
    
 
db.FindinCol1().then(function(items) { 
 
    console.info('The promise was fulfilled with items!', items); 
 
}, function(err) { 
 
    console.error('The promise was rejected', err, err.stack); 
 
});

Teraz, bardziej aktualnych wersjach kierowca node.js MongoDB posiada natywne wsparcie dla obietnic nie musisz wykonywać żadnej pracy, aby zawijać zwroty w obietnicach, jak wyżej.Jest to o wiele lepszy przykład, jeśli używasz najświeższe kierowcy:

// db1.js 
 
var MongoClient = require('mongodb').MongoClient; 
 
         
 
module.exports = { 
 
    FindinCol1: function() { 
 
    return MongoClient.connect('mongodb://localhost:27017/db1').then(function(db) { 
 
     var collection = db.collection('col1'); 
 
     
 
     return collection.find().toArray(); 
 
    }).then(function(items) { 
 
     console.log(items); 
 
     return items; 
 
    }); 
 
    } 
 
}; 
 

 

 
// app.js 
 
var db = require('./db1'); 
 
    
 
db.FindinCol1().then(function(items) { 
 
    console.info('The promise was fulfilled with items!', items); 
 
}, function(err) { 
 
    console.error('The promise was rejected', err, err.stack); 
 
});

Promises stanowią doskonałą metodę asynchroniczny przepływ sterowania, bardzo polecam poświęcić trochę czasu na zapoznanie się z nimi.

+0

Muszę mieć nowszą wersję, ponieważ twoja druga opcja działa świetnie. – MM1

+0

Nie mogę ci wystarczająco podziękować! Będę czytać z obietnicami. – MM1

+0

Dzięki! Świetne rozwiązania! Ale w drugim przypadku wydaje się, że nie potrzebujemy sekundy. Czy jest jakiś powód, dla którego go tam umieściłeś? –

2

Tak, jest to kod asynchroniczny, a dzięki return otrzymasz obiekt MongoClient lub nic, zależnie od miejsca, w którym się znajdujesz.

Należy użyć parametr callback:

module.exports = { 
    FindinCol1 : function funk1(callback) { 
    MongoClient.connect("mongodb://localhost:27017/db1", function (err,db) { 
     if (err) { 
     return console.dir(err); 
     } 
     var collection = db.collection('col1'); 
     collection.find().toArray(function (err, items) { 
     console.log(items);  
     return callback(items);  
     }); 
    }); 
    } 
}; 

przekazać funkcję oddzwonienia do FindinCol1:

a.FindinCol1(function(items) { 
    console.log(items); 
}); 

Proponuję, aby sprawdzić ten artykuł: https://docs.nodejitsu.com/articles/getting-started/control-flow/what-are-callbacks

+0

Ta opcja również działa. Dziękuję Ci. Żadne z nich nie blokuje kodu. – MM1

Powiązane problemy