-1

I want to use the mongodb connection in other modules also so I chose this approach. Is there any drawback or something that I should be aware of. I am going to require this file in my app.js file. or Is there any other elegant way of doing the same thing .

const uri = "mongodb://localhost";
const MongoClient = require('mongodb').MongoClient;
const client = new MongoClient(uri, { useNewUrlParser: true });

db = null ;
client.connect().then(()=>{
    db = client.db("mydb");
    db.collection("users").createIndex({ mobno: 1 }, { sparse: true, unique: true });
}).catch((error)=>{
    db = error;
});
while(true){
    if (db!=null){
        module.exports = db;
        break;
    }
}
Namit Piriya
  • 141
  • 7
  • Does this answer your question? [What is best way to handle global connection of Mongodb in NodeJs](https://stackoverflow.com/questions/49397608/what-is-best-way-to-handle-global-connection-of-mongodb-in-nodejs) – maxpaj Jan 25 '20 at 18:30
  • What is that busy loop for? – Dave Newton Jan 25 '20 at 18:31
  • Lots of things wrong with this. For starters, your `while(true)` loop blocks the event loop so `db` can never get a value so your loop never completes. Did you actually run this? It will just be an infinite loop. Until we have top level `await` that works with module initialization (which is being worked on), you cannot directly export a value obtained asynchronously. Instead, you can export a promise and the caller has to use the promise to get the db. Or export a function that returns a promise. – jfriend00 Jan 25 '20 at 18:33
  • That's because I don't want null when I am using connection in other module. When I required this module in app.js I will be sure that my connection is opened – Namit Piriya Jan 25 '20 at 18:33
  • I guess @jfriend00 is right by this I will block the event loop and db will never get it's value – Namit Piriya Jan 25 '20 at 18:39

1 Answers1

0

Lots of things wrong with this. This concept won't work.

For starters, your while(true) loop blocks the event loop so db can never get a value so your loop never completes.

When the network operation in the connect completes, it will add an event to the event queue and the callback associated with it (and then the resolved promise) can only run when you return control back to the event loop so that event can get processed.

But, your while(true) loop blocks the event loop so no events can get processed. Unless you're using await inside the loop (which allows other events to run), you can't use a wait loop like this in node.js. It just creates an infinite loop.

Until we have top level await that works with module initialization (which is being worked on), you cannot directly export a value obtained asynchronously.

Instead, you can export a promise and the caller has to use the promise to get the db. Or export a function that returns a promise.

More info on problems with the busy-wait while loop in these other answers:

Wait until flag=true

javascript - What is wrong with this while loop? never ending loop

Why does a while loop block the event loop?

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I understood that this will block the event loop and the call in then will never be executed by the event loop.Can you share any resources or code which uses async await. – Namit Piriya Jan 26 '20 at 08:30
  • is below code is the right way – Namit Piriya Jan 26 '20 at 08:34
  • db = null ; module.exports = client.connect().then(()=>{ db = client.db("mydb"); db.collection("users").createIndex({ mobno: 1 }, { sparse: true, unique: true }); return db ; }).catch((error)=>{ db = error; }); – Namit Piriya Jan 26 '20 at 08:35
  • @NamitPiriya - `async/await` won't really help you here. There is NO way to directly export an asynchronously retrieved value. You have to export a promise that the caller can use to get the value or the caller has to register a callback. The db finishes its connection some indeterminate time in the future long AFTER `module.exports` has been assigned and the module is done loading. There is a future proposal for nodejs for top level `await` along with asynchronous module loading, but that is not something we have yet. – jfriend00 Jan 26 '20 at 19:00