Having async/await by itself in a function would return a "pending value" but if a promise used then the actual value will be returned in the end. Is this the ideal way to wait for the completion of asynchronous operations?
This returns exactly what I want
var foundForm = await getDocument(query) //Returns the resulting document
async function getDocument(query){
return new Promise((resolve,reject) =>{
MongoClient.connect (url, async function(err, db) {
if (err) throw err;
console.log(query)
db.collection("users").find(query).toArray(function(err, result) {
if (err) {
console.log(err)
throw err;
}
console.log(result);
db.close();
resolve(result) // returns result;
});
});
})
}
This doesnt return what I need:
var foundForm = await getDocument(query) //Returns 'pending'
async function getDocument(query){
MongoClient.connect (url, async function(err, db) {
if (err) throw err;
console.log(query)
db.collection("users").find(query).toArray(function(err, result) {
if (err) {
console.log(err)
throw err;
}
console.log(result);
db.close();
return result;
});
})
}
Since your getDocument
code needs to wait for an asynchronous operation that doesn't provide a Promise interface, getDocument
shouldn't be an async
function, because you need to create the promise manually. (And the callback you give to a non-promise-focussed function should almost never be an async
function.)
function getDocument(query){
return new Promise((resolve,reject) =>{
MongoClient.connect(url, function(err, db) {
if (err) {
// Reject, don't throw
reject(err);
return;
}
console.log(query);
db.collection("users").find(query).toArray(function(err, result) {
if (err) {
// Reject, don't throw
reject(err);
return;
}
console.log(result);
db.close();
resolve(result);
});
});
});
}
Alternately, use promise-enabled versions of MongoClient.connect
and db.collection("users").find
. MongoDB has those available in its JavaScript API now (I'm afraid I don't have the details). Then you'd use an async
function with await
, something like this (according to this blog post):
// BE SURE TO DOUBLE-CHECK THE DETAILS
async function getDocument(query){
const db = await MongoClient.connect(url);
const await result = db.collection("users").find(query).toArray();
console.log(result);
await db.close(); // No idea whether you need `await` here or not
return result;
}
(And the callback you give to a non-promise-focussed function should almost never be an async function.) - Why is this considered bad? What would be the consequences to this?
Also the MongoDB javascript API snippet looks clean and fresh, awesome
@d12 - Because
async
functions always return a promise, but if the thing they're returning that promise to doesn't do anything with the promise, it sets you up for unhandled rejection errors. It also misleads you (and your potential readers), by giving the impression that the thing you're returning the promise to will do something useful with it. One classic example is people usingforEach
on an array and passing in anasync
callback, then wondering why it is that all of the array entries are passed throughforEach
before the first one is done with its work. :-)Fabulous, this makes sense now!