我正在创建一个帖子挂钩,以在保存帖子后创建一个 slug。当我尝试使用 Postman 检查结果时,该过程陷入困境(未返回任何数据)。我正在使用 [电子邮件受保护]。
后挂钩代码:
PostsSchema.post("save", async function (doc, next) {
try {
doc.postSlug = slugify(doc.postTitle, { lower: true });
await doc.save();
return next();
} catch (err) {
console.log("inside catch method");
return next(createError(500, err.message));
}
});
我使用的路线代码:
module.exports.createPost = async (req, res, next) => {
const { postTitle, postContent, postAuthor } = req.body;
try {
// check if author exist
const authorExist = await AccountsModel.findById(postAuthor);
if (!authorExist) {
return next(createError(404, `Author ID: ${postAuthor} Not Found`));
}
// create post
console.log("route 1")
const postNew = new PostsModel({
postTitle: postTitle,
postContent: postContent,
postAuthor: postAuthor,
});
await postNew.save();
// populate data for return
let postCreated = await postNew.populate("postAuthor");
return res.status(200).json({
code: 1,
success: true,
message: "New Post Created",
data: postCreated,
});
} catch (error) {
return next(createError(500, error.message));
}
};
我确实通过删除
await
前面的 doc.save()
来修复此问题:
PostsSchema.post("save", async function (doc, next) {
try {
doc.postSlug = slugify(doc.postTitle, { lower: true });
doc.save();
return next();
} catch (err) {
console.log("inside catch method");
return next(createError(500, err.message));
}
});
此外,使用
.then()
也会返回结果:
PostsSchema.post("save", async function (doc, next) {
doc.postSlug = slugify(doc.postTitle, { lower: true });
console.log(1);
doc
.save()
.then(() => {
console.log(2);
return next();
})
.catch((error) => {
return next(createError(500, err.message));
});
});
但发现其他一些帖子有等待,答案表明这不是问题:
所以,我想知道是等待破坏了进程还是其他原因?
我发现了问题,当我在你的帖子挂钩中
console.log(1)
时,它会创建一个无限循环。根据帖子Mongoose post save hook 1下的评论,更新文档,post hook在执行.save()
后执行;在你的 post hook 中,你执行另一个 .save()
再次调用你的 post hook,创建一个无限循环。
你的
await doc.save()
不起作用,因为它正在等待无限循环完成。这就是为什么邮递员没有回复,它从未到达return next()
。
您的
doc.save()
“有效”,因为.save()
是异步的,在完成之前它已经返回next()
,这就是为什么有一个值返回给邮递员而代码保持在无限循环中。
您的
doc.save().then()
“有效”,因为 .then()
解析了您的 .save()
并到达 return next()
,但它再次调用 post 挂钩,从而创建无限循环。
我建议更改 hook 中的关键字 pass 或更改为 pre hook:
PostsSchema.pre('save', function(next) {
if (this.isNew || this.isModified('PostTitle')) {
this.slug = slugify(this.PostTitle, { lower: true });
}
return next();
});
此预挂钩在实际
save()
操作之前运行,因此保存后不会再次调用此挂钩。