Recent versions of Mongoose returns a Promise as well as providing the regular callback-style pattern. Since async functions are syntatic sugar over Promises, you can await calls to Mongoose methods.
async function clearUsers () {
try {
await User.remove({})
let admin = new User({
email: '[email protected]',
password: 'dapdap'
})
await admin.save()
console.info('Success')
mongoose.disconnect()
} catch (e) {
console.error(e)
}
}
Some things to keep in mind:
async functions always returns a Promise. If you don't return anything from an async function, it will still return a Promise that resolves when execution of that function finishes, but will not resolve with any value.
try/catch in an async function works the same as for regular, synchronous code. If any function call in the try body throw or return a Promise that rejects, execution stops right on that line and proceeds to the catch body.
- Rejected promises "trickle" up the function call chain. This means that the top-most callee can handle errors. See the below example:
This is an anti-pattern that should be avoided unless you absolutely need to handle an error in a specific function, possibly to provide a return value from a different source:
async function fn1 () {
throw new Error("Something went wrong")
}
async function fn2 () {
try {
await fn1()
} catch (e) {
throw e
}
}
async function fn3 () {
try {
await fn2()
} catch (e) {
throw e
}
}
async function run () {
try {
await fn3()
} catch (e) {
console.error(e)
}
}
The above could rather be implemented like the below and still catch the error, not resulting in a runtime panic/crash:
async function fn1 () {
throw new Error("Something went wrong")
}
function fn2 () {
return fn1()
}
function fn3 () {
return fn2()
}
async function run () {
try {
await fn3()
} catch (e) {
console.error(e)
}
}
There are multiple ways to write the above code that will all be valid, so I recommend that you explore these.
Keeping the above examples in mind, your function clearUsers() could then be rewritten to this:
async function clearUsers () {
await User.remove({})
let admin = new User({
email: '[email protected]',
password: 'dapdap'
})
await admin.save()
mongoose.disconnect()
}
And then possibly called in two different ways;
By interacting with the Promise returned directly:
clearUsers()
.then(() => {
console.log('Success')
})
.catch((e) => {
console.error(e)
})
Or from within another async function:
(async function () {
try {
await clearUsers()
console.log('Success')
} catch (e) {
console.error(e)
}
})()
If any function call within the clearUsers() function throws, for example await admin.save(), execution will stop on that line and return a rejected Promise which will be caught in the corresponding catch blocks in both variants.