【发布时间】:2020-10-29 06:09:27
【问题描述】:
我正在通过创建一个简单的博客应用程序来学习使用 MongoDB。但是,我保存给定帖子的部分代码似乎偶尔会出现承诺问题,但并非总是如此,而代码是否成功似乎只是运气。
我数据库中的每个帖子都使用以下架构存储:
{
title: String,
author: String,
body: String,
slug: String,
baseSlug: String,
published: { type: Boolean, default: false }
}
slug 定义用于访问博客文章的链接,并根据博客文章的标题自动生成。但是,如果文章标题重复,slug 将在末尾添加一个数字以区别于类似文章,而baseSlug 将保持不变。例如:
- 我创建了帖子
"My first post",并为其分配了"my-first-post"的baseSlug。因为没有其他帖子具有相同的baseSlug,所以slug也设置为"my-first-post"。 - 我创建了另一个名为
"My first post"的帖子,它被分配了"my-first-post"的baseSlug。但是,由于另一个帖子具有相同的baseSlug,因此它被分配了slug"my-first-post-1"。
为了创建这种行为,我在 Express 中编写了以下 addpost 路由:
app.post("/addpost", (req, res) => {
let postInfo = req.body;
for (key of Object.keys(postInfo)) {
if (postInfo[key] == "true") postInfo[key] = true;
}
let slug = postInfo.title
.toLowerCase()
.split(" ")
.filter(hasNumber) // return /\d/.test(str);
.slice(0, 5)
.join("-");
postInfo.slug = slug;
var postData;
Post.find({ baseSlug: postInfo.slug }, (error, documents) => {
if (documents.length > 0) {
let largestSlugSuffix = 0;
for (let document of documents) {
var fullSlug = document.slug.split("-");
var suffix = fullSlug[fullSlug.length - 1];
if (!isNaN(suffix)) {
if (parseInt(suffix) > largestSlugSuffix) {
largestSlugSuffix = suffix;
}
}
}
largestSlugSuffix++;
postInfo.baseSlug = postInfo.slug;
postInfo.slug += "-" + largestSlugSuffix;
} else {
postInfo.baseSlug = postInfo.slug;
}
postData = new Post(postInfo);
})
.then(() => {
postData
.save()
.then(result => {
res.redirect("/");
})
.catch(err => {
console.log(err);
res.status(400).send("Unable to save data");
});
})
.catch(err => {
console.log(err);
res.status(400).send("Unable to save data");
});
});
这段代码似乎大部分时间都可以工作,但有时会失败,并输出以下内容:
TypeError: Cannot read property 'save' of undefined
at C:\Users\User\BlogTest\app.js:94:18
at processTicksAndRejections (internal/process/task_queues.js:94:5)
(供参考,我文件中的第 94 行是postData.save())
我怀疑这是因为函数主体的执行时间比它应该执行的要长,而且 postData 变量尚未定义。但是,由于.then() 回调函数,postData.save() 不应该在 Promise 完成之前执行。
为什么我的代码会这样?有什么办法可以解决吗?
【问题讨论】:
标签: javascript node.js express mongoose promise