我有一个nodejs后端,可以使用Mongoose快速处理API到mongo DB的路由。我已经更改了代码,以使其更易于理解,但实际上我正在构建任务列表。
我有一个用于将任务添加到任务列表的端点,我想维护一个任务列表,以便稍后进行一些分析。我遇到的问题是我想检查一个任务是否已经存在,如果该任务不存在,那么我想在任务模型中创建它,然后将其添加到taskList中。如果确实存在,那么我只想将其添加到任务列表中。
我的第一个想法是在创建任务时在保存操作上使用异步,因为我想避免嵌套承诺的数量,因为这使它非常难以理解。但是,当我的nodejs服务器启动时,它给我一个错误SyntaxError: await is only valid in async function
,但是从文档中可以在保存时使用await,并且我的函数具有async关键字。所以我不知道我在做什么错。
exports.tasklists_add_task = async (req, res, next) => {
const id = req.params.tasklistId;
Task.findOne({ externalId: req.body.externalId })
.exec()
.then(doc => {
let task = doc;
if (!task) {
task = new Task({
_id: new mongoose.Types.ObjectId(),
externalId: req.body.externalId,
name: req.body.name
});
await task.save();
}
tasklist.update({_id: id}, {$push: { tasks: tasks }})
.select("-__v")
.exec()
})
.then(result => {
...
})
.catch(err => { ... })
}
我有2个架构,即“任务架构”
const mongoose = require("mongoose");
const taskSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
externalId: { type: String, required: true },
name: { type: String, required: true }
});
module.exports = mongoose.model("Task", taskSchema);
和任务列表架构
const mongoose = require("mongoose");
const taskListSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
user: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true },
type: { type: String, required: true },
tasks: [{ type: mongoose.Schema.Types.ObjectId, ref: "Type" }]
});
module.exports = mongoose.model("TaskList", taskListSchema);
我不必在这里使用async await,我可以只链接promise,但是我无法解决如何以逻辑可读的方式链接promise,因为如果不存在,我必须创建任务
答案 0 :(得分:1)
await
仅在异步函数中允许(前提是您使用的是支持它的环境)。 Await
仅在async
函数中有效,而您的await
在不异步的回调中-只有您的顶级函数是async
。您在这里错过了关键字:
.then(doc => {
// Should be:
.then(async doc => {
这样,您就可以告诉代码doc
回调是异步函数。但是,当您的环境中有async/await
时,可以将整个块重构为类似的样子!
exports.tasklists_add_task = async (req, res, next) => {
const id = req.params.tasklistId;
try {
let task = await Task.findOne({ externalId: req.body.externalId })
.exec();
if (!task) {
task = new Task({
_id: new mongoose.Types.ObjectId(),
externalId: req.body.externalId,
name: req.body.name
});
await task.save();
}
const result = await tasklist.update({_id: id}, {$push: { tasks: tasks }}).select("-__v").exec();
} catch (err) {
// Error handling here
}
}
在大多数情况下,无需将async/await
和then
混合使用。可以将其视为处理承诺并将then/catch
隐藏在顺序易读的代码后面的绝佳方式。
我建议调整代码,使其看起来像提出的解决方案(将Promises和Async / Await大量混合使用被认为是某种反模式)。