Javascript (Mongo/Mongoose)如何处理多个查询结果的等待
我正在写一个Discord机器人,它可以为文本和语音频道的使用生成每周的公会统计数据。我的代码将几个Mongo查询划分为不同的方法:Javascript (Mongo/Mongoose)如何处理多个查询结果的等待,javascript,mongodb,mongoose,discord,Javascript,Mongodb,Mongoose,Discord,我正在写一个Discord机器人,它可以为文本和语音频道的使用生成每周的公会统计数据。我的代码将几个Mongo查询划分为不同的方法: function getTopActiveTextChannels() { let topTextChannels = [] ChannelModel.find({}).sort({"messageCountThisWeek": -1}).limit(topLimit) .exec(channels => { channels.forE
function getTopActiveTextChannels() {
let topTextChannels = []
ChannelModel.find({}).sort({"messageCountThisWeek": -1}).limit(topLimit)
.exec(channels => {
channels.forEach(c => {
topTextChannels.push({"name": c.name, "messageCount": c.messageCount})
})
console.log(topTextChannels)
return topTextChannels
})
}
function getTopActiveVoiceMembers() {
let topVoiceMembers = []
UserModel.find({}).sort({"timeSpentInVoice": -1}).limit(topLimit)
.exec(users => {
users.forEach(u => {
topVoiceMembers.push({"username": u.username, "timeSpentInVoice": u.timeSpentInVoice})
})
console.log(topVoiceMembers)
return topVoiceMembers
})
}
然后我有一个方法可以调用这两个函数,并且(目前)将值打印到控制台:
function getWeeklyGuildStats(client) {
let topActiveTextChannels = getTopActiveTextChannels()
let topVoiceMembers = getTopActiveVoiceMembers()
let promisesArray = [topActiveTextChannels, topVoiceMembers]
Promise.all(promisesArray).then(values => {console.log(values)})
}
执行getWeeklyBuilderStats(客户端)
输出:[未定义,未定义]
。我确信我没有正确使用承诺,但当我遵循Mongoose的文档时,它告诉我使用exec()
而不是then()
,但我得到了一个channels=null
错误
有什么事让人吃惊吗?这似乎是一种相当普遍的模式。有没有人能在一个方法中解决多个Mongoose查询的问题?
承诺。所有的
都应该有一个承诺数组,而你的函数都返回普通数组,所以你需要在helper方法中返回整个查询,以获取用户和频道,然后在承诺之后执行逻辑。全部
您的函数可能看起来像这样
function getTopActiveTextChannels() {
return ChannelModel.find({}).sort({"messageCountThisWeek": -1}).limit(topLimit).exec();
}
function getTopActiveVoiceMembers() {
return UserModel.find({}).sort({"timeSpentInVoice": -1}).limit(topLimit).exec();
}
那么调用这两个方法的函数将类似于
function getWeeklyGuildStats(client) {
let topActiveTextChannels = getTopActiveTextChannels()
let topVoiceMembers = getTopActiveVoiceMembers()
let promisesArray = [topActiveTextChannels, topVoiceMembers]
Promise.all(promisesArray).then(values => {
console.log(values);
// here you could do your own logic, the for loops you did in the helper methods before
});
}
在函数的根级别没有任何return语句,因此它们总是同步返回未定义的
。我不熟悉您正在使用的库,但是如果例如ChannelModel.find({}).exec(callback)
返回一个承诺,返回值为callback
,正如您的代码所示,那么您只需要向函数添加一个return
语句
例如:
函数getTopActivateXTChannels(){
让topTextChannel=[]
//返回这个!(假设它返回一个承诺。)否则您总是返回“未定义”。
返回ChannelModel.find({}).sort({“messageCountThisWeek”:-1}).limit(topLimit)
.exec(频道=>{
channels.forEach(c=>{
推送({“name”:c.name,“messageCount”:c.messageCount})
})
console.log(TopTextChannel)
返回TopTextChannel
})
}
OK,将参数修改为Promise.all()
作为方法调用。仍在获取输出[undefined,undefined]
完成查询后,您是否可以尝试console.log用户和频道?我的意思是在之后记录用户。然后在getTopActiveVoiceMembers函数中,对通道也一样?我在每个方法的返回值之前添加了console.log
语句。topTextChannel
和topVoiceMembers
都在打印正确的数据。我已经编辑了我的答案,你现在可以检查一下吗?,希望现在能有所帮助。我已经重新组织了我的查找方法,以返回Mongoose承诺,并将.then()
逻辑移到了单独的助手方法,我从主方法调用了这些方法。谢谢,这就成功了!