2016-02-06 10 views
9

Sono nuovo al nodo e mongo dopo 15 anni di VB6 e MySql. Sono sicuro che questo non è ciò che verrà utilizzato dal mio programma finale, ma ho bisogno di capire come chiamare una funzione in un altro modulo e ottenere risultati.Node.js, Mongo trova e restituisce i dati

Desidero che un modulo abbia una funzione per aprire un DB, trovare in una raccolta e restituire i risultati. Potrei voler aggiungere ancora un paio di funzioni in quel modulo per altre collezioni. Per ora ho bisogno che sia il più semplice possibile, posso aggiungere gestori di errori, ecc. Sono stato su questo per giorni cercando diversi metodi, module.exports = {... attorno alla funzione e senza di essa, .send, restituisci tutto senza fortuna. Capisco che sia asincrono, quindi il programma potrebbe aver passato il punto di visualizzazione prima che i dati siano lì.

Ecco cosa ho provato con Mongo che esegue un database di db1 con una raccolta di 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 (articoli) funziona quando chiamate il 'FindinCol1' ma non console.log (b) (restituisce 'indefinito') in modo da non sto ricevendo il ritorno o sto incollato dal il tempo è tornato. Ho letto dozzine di post e ho guardato decine di video, ma a questo punto sono ancora bloccato. Qualsiasi aiuto sarebbe molto apprezzato.

risposta

16

Come accennato in un altro risposta, questo codice è asincrono, non è possibile semplicemente restituire il valore desiderato lungo la catena di callback (nest funzioni ed). È necessario esporre un'interfaccia che consente di segnalare il codice chiamante una volta ottenuto il valore desiderato (quindi, richiamandolo o richiamato).

C'è un esempio di callback fornito in un'altra risposta, ma esiste un'opzione alternativa che vale la pena esplorare: promises.

Invece di una funzione di richiamata che si chiama con i risultati desiderati, il modulo restituisce una promessa che può entrare in due stati, soddisfatti o respinti. Il codice chiamante attende la promessa di entrare in uno di questi due stati, chiamata la funzione appropriata quando lo fa. Il modulo attiva il cambio di stato di resolve ing o reject ing. In ogni modo, ecco un esempio utilizzando promesse:

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

Ora, più fino a versioni aggiornate dei driver dei node.js mongodb hanno il supporto nativo per le promesse, non devi fare alcun lavoro per avvolgere i callback in promesse come sopra.Questo è un esempio molto meglio se si utilizza un fino a conducente Data:

// 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); 
 
});

promesse forniscono un metodo eccellente per il flusso di controllo asincrono, mi raccomando trascorrere un po 'di tempo a familiarizzare con loro.

+0

Devo eseguire una versione più recente poiché la seconda opzione funzionava alla grande. – MM1

+0

Non posso ringraziarti abbastanza! Leggerò le promesse. – MM1

+0

Grazie! Grandi soluzioni! Ma nel secondo modo, non sembra che abbiamo bisogno del secondo, allora. C'è un motivo per cui lo metti lì? –

2

Sì, questo è un codice asincrono e con uno return si otterrà l'oggetto MongoClient o nulla, in base a dove si inserisce.

Si dovrebbe utilizzare un parametro di 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);  
     }); 
    }); 
    } 
}; 

passa una funzione di callback per FindinCol1:

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

vi consiglio di controllare questo articolo: https://docs.nodejitsu.com/articles/getting-started/control-flow/what-are-callbacks

+0

Questa opzione funziona anche. Grazie. Né sembra bloccare il codice. – MM1

Problemi correlati