1、await 不能用在 forEach 中
在forEach中使用await的话,await不会生效,因此在forEach中执行异步操作时,使用await进行数据处理的话会出问题,不会按照你预期的结果处理,因为forEach 只支持同步代码。
forEach简化以后的伪代码:
while (index < arr.length) {
callback(item, index) //即我们传入的回调函数
}
forEach 只是简单执行了下回调函数而已,并不会去处理异步的情况。
总结:要想在循环中使用async await,并且想让forEach按照你预期的结果进行处理的话,请使用for…of 或者 for 循环。
2、mongoose(mongodb)查询数据库后,往查询到的数组或对象上添加新属性的操作是无效的。
因为mongoose查询出来的对象是document对象,并不是普通的javascript对象,如果没有转换为普通的javascript对象,直接在查出的对象上添加新属性是无效的(在new mongoose.Schema({ xxx:xxx})里没有该字段)。
解决方法一是往new mongoose.Schema()里添加新属性所属字段(不推荐)
解决方法二是使用mongoose的Document.prototype.toObject()方法将document对象转换为普通的javascript对象,然后就可以使用javascript object的方法去设置新属性了(推荐)
//forumList 是一个数组,无法使用Document.prototype.toObject()方法
//如果forumList 是一个对象的话,就可以直接这样处理
//let forumList = await commentSchema.find({ articleId: { $exists: false } });
//forumList = forumList.toObject();
const forumList = await commentSchema.find({ articleId: { $exists: false } });
//定义一个新数组以存储转换后的javascript对象,否则在旧数组中同样看不到新增的属性
const newForumList = [];
//对评论信息数组的处理
if (forumList.length > 0) {
for (let item of forumList) {
//将数组中的每个mongodb的document对象转换为普通的javascript对象,
// 否则mongodb的document对象是无法新增属性的
item = item.toObject();
const user = await userSchema.findOne({ _id: item.fromId });
item.fromNickName = user.nickname//发表评论的用户的昵称
item.fromImg = user.avatar//发表评论的用户的头像
newForumList.push(item);
if (item.children.length > 0) {
for (const innerItem of item.children) {
const innerFromUser = await userSchema.findOne({ _id: innerItem.fromId });
innerItem.fromNickName = innerFromUser.nickname//发表子评论的用户的昵称
innerItem.fromImg = innerFromUser.avatar//发表子评论的用户的头像
const innerToUser = await userSchema.findOne({ _id: innerItem.toId });
innerItem.toNickName = innerToUser.nickname//被回复人的昵称
}
}
}
}
3、接口路径问题
我在后端已经设置允许跨域了,前端其它接口都能成功请求,唯独其中一个post请求老是请求失败,其它post请求是成功的,然后控制台报以下错误:
这让我立马认为是跨域问题,我就在纳闷:明明允许跨域了,为啥还有跨域问题啊?然后就在网上疯狂找解决跨域问题的资料,用了一个晚上,还是没有成功,之后就仔仔细细地看了这个接口与其它接口的不同之处,结果我傻眼了,我后端路径开头没有加“ / ”,我的天,这个错误明明是找不到路径,应该报404的,结果给我报跨域的错误,害我浪费了一个晚上找资料,我是真的服了,以后写代码还是要更加仔细才行,不然会让自己花费更多时间解决问题。
4、vue实现点击组件外的地方隐藏该组件
<el-card v-show="isCardShow" class="box-card" ref="card">
<div v-for="o in 4" :key="o" class="text item">
{{ "列表内容 " + o }}
</div>
</el-card>
//在DOM元素渲染之前开始监听mousedown事件
beforeMount() {
document.body.addEventListener("mousedown", this.closeCard);
},
//在vue文件销毁的时候移除mousedown事件
beforeDestroy() {
document.body.removeEventListener("mousedown", this.closeCard);
},
methods: {
//隐藏卡片
closeCard(e) {
// 如果点击发生在当前组件内部,则不处理
if (this.$refs.card.$el.contains(e.target)) {
return;
}
this.isCardShow = false;
},
}