MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Comportamento di require in node.js

Ci sono 3 punti chiave da capire qui e poi li spiegherò in dettaglio.

  1. module.exports è un oggetto e gli oggetti vengono passati per copia di riferimento in JavaScript.
  2. require è un sincrono funzione.
  3. client.connect è un asincrono funzione.

Come hai suggerito, è una questione di tempismo. node.js non può sapere che module.exports cambierà in seguito. Non è un problema. Come fa a saperlo?

Quando require viene eseguito, trova un file che soddisfa i suoi requisiti in base al percorso immesso, lo legge e lo esegue e memorizza nella cache module.exports in modo che altri moduli possano require lo stesso modulo e non è necessario reinizializzarlo (il che rovinerebbe l'ambito delle variabili, ecc.)

client.connect è una chiamata di funzione asincrona, quindi dopo averlo eseguito, il modulo termina l'esecuzione e require call memorizza una copia del riferimento module.exports e lo restituisce a users.js. Quindi imposti module.exports = db , ma è troppo tardi. Stai sostituendo il riferimento module.exports con un riferimento a db, ma l'esportazione del modulo nel nodo require la cache punta al vecchio oggetto.

È meglio definire module.exports come una funzione che otterrà una connessione e quindi la passerà a una funzione di callback in questo modo:

var mongodb = require("mongodb");
var client = mongodb.MongoClient;

module.exports = function (callback) {
    client.connect('mongodb://host:port/dbname', { auto_reconnect: true },
          function(err, db) {
             if (err) {
                console.log(err);
                callback(err);
             } else {
                // export db as member of exports
                callback(err, db);
             }
          }
    )
};

Avviso:sebbene non rientri nell'ambito di questa risposta, fai molta attenzione con il codice sopra per assicurarti di chiudere/restituire le connessioni in modo appropriato, altrimenti perderai le connessioni.