最近版本的 Mongoose 返回一个 Promise 并提供常规的回调样式模式。由于 async 函数是 Promises 的语法糖,因此您可以 await 调用 Mongoose 方法。
async function clearUsers () {
try {
await User.remove({})
let admin = new User({
email: 'admin@dap.com',
password: 'dapdap'
})
await admin.save()
console.info('Success')
mongoose.disconnect()
} catch (e) {
console.error(e)
}
}
注意事项:
-
async 函数 总是 返回一个 Promise。如果您没有从 async 函数返回任何内容,它仍会返回一个 Promise,该 Promise 会在该函数执行完成时解析,但不会解析为任何值。
-
async 函数中的 try/catch 与常规同步代码的工作方式相同。如果在try 主体throw 中任何 函数调用或返回一个拒绝 的Promise,则执行将在该行直接停止并继续到catch 主体。
- 被拒绝的承诺“涓涓”函数调用链。这意味着最顶层的被调用者可以处理错误。请参阅以下示例:
这是一种应该避免的反模式,除非您绝对需要处理特定函数中的错误,可能是为了提供来自不同来源的返回值:
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)
}
}
上面可以像下面这样实现,但仍然会捕获错误,不会导致运行时恐慌/崩溃:
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)
}
}
上面的代码有多种写法都是有效的,所以我建议你去探索这些。
记住上面的例子,你的函数 clearUsers() 可以重写为:
async function clearUsers () {
await User.remove({})
let admin = new User({
email: 'admin@dap.com',
password: 'dapdap'
})
await admin.save()
mongoose.disconnect()
}
然后可能以两种不同的方式调用;
通过与直接返回的 Promise 交互:
clearUsers()
.then(() => {
console.log('Success')
})
.catch((e) => {
console.error(e)
})
或者来自另一个异步函数:
(async function () {
try {
await clearUsers()
console.log('Success')
} catch (e) {
console.error(e)
}
})()
如果clearUsers() 函数中的任何 函数调用抛出,例如await admin.save(),执行将在该行停止并返回一个rejected Promise,该Promise 将被捕获在两个变体中对应的 catch 块中。