nodejs中的异步foreach和mongoose
Posted
技术标签:
【中文标题】nodejs中的异步foreach和mongoose【英文标题】:async foreach and mongoose in nodejs 【发布时间】:2021-04-08 09:39:37 【问题描述】:在猫鼬中,我建立了类似于猫鼬文档的关系,现在我想要一个对象数组
对象是我们拥有的对象的子对象
例如在 tweeter 中,一个用户有很多推文,每条推文都有标题、内容和作者
有人给我们用户 ID,我们给他所有推文用户的标题和内容数组
[
title: 'title01', content: 'aaaaaa',
title: 'title02', content: 'bbbbb',
.
.
.
]
我试试
const username = req.params.username;
User.find( username: username , (err, docs) =>
if (err) return res.json( err: true );
if (docs.length > 0)
let lives: Array<Object> = [];
docs[0].lives.forEach((live, idx) =>
Live.find( _id: live , (err, docs) =>
lives.push(docs[0]);
);
);
else
return res.json( err: true );
);
lives 有标题内容和作者(在 DB 中我将其命名为用户) 但是因为 aSync 我无法在 forEach 之后获得生命 :)
更新:
直播模式:
const schema = new mongoose.Schema(
title:
type: String,
required: true,
,
content:
type: String,
required: true,
,
user:
type: mongoose.Schema.Types.ObjectId,
ref: "users",
required: true,
,
);
用户模式:
import ArraySortOptions from "joi";
import mongoose, Model from "mongoose";
interface IUser extends mongoose.Document
email: string;
username: string;
password: string;
lives: Array<mongoose.Schema.Types.ObjectId>;
const schema: mongoose.Schema = new mongoose.Schema(
username:
type: String,
required: true,
,
password:
type: String,
required: true,
,
email:
type: String,
required: true,
,
lives: [
type: mongoose.Schema.Types.ObjectId,
ref: "lives",
,
],
);
const User: Model<IUser> = mongoose.model("users", schema);
export default User;
【问题讨论】:
【参考方案1】:我会这样做:
const username = req.params.username;
User.find( username: username , async (err, docs) =>
if (err) return res.json( err: true );
if (docs.length > 0)
// start with asnyc queries
let livePromises = [];
for (let live of docs[0].lives)
// push new promise which resolves the docs[0] of this live id
livePromises.push(new Promise(resolve =>
Live.find( _id: live , (err, docs) =>
resolve(docs[0]);
);
// await all query results parallel
let lives = await Promise.all(livePromises);
// use lives variable as you want
return res.json( lives: lives );
else
return res.json( err: true );
);
我不确定你使用的是哪种类型的系统(你写了lives: Array<Object>
),所以我跳过了。根据需要修改我的建议。
如果您对此答案或一般Promises 有任何疑问,请写评论。
【讨论】:
我用打字稿 Promise.all 做什么? Promise.all() 方法将一个可迭代的 Promise 作为输入,并返回一个 Promise,该 Promise 解析为输入 Promise 的结果数组。【参考方案2】:最好使用 Mongoose 的内置 populate()
方法,该方法允许您引用其他集合中的文档,类似于 MongoDB 版本 >= 3.2 中的类似联接的 $lookup
聚合运算符。
由于populate()
需要附加查询,因此使用User.findOne()
查询与我们在参数中提供的用户名匹配的单个用户。
使用 async/await 可以如下完成:
const username = req.params;
const user = await User.findOne( username ).populate('lives');
console.log(user.lives); // ---> [title: 'title01', content: 'aaaaaa', ... ]
【讨论】:
以上是关于nodejs中的异步foreach和mongoose的主要内容,如果未能解决你的问题,请参考以下文章
NodeJs, javascript: .forEach 似乎是异步的?需要同步