Mongoose exec() 没有正确等待
Posted
技术标签:
【中文标题】Mongoose exec() 没有正确等待【英文标题】:Mongoose exec() does not await properly 【发布时间】:2020-11-23 13:46:12 【问题描述】:由于某种原因,exec() 没有在我的代码中等待:
let team = <SOME TEAM NAME> //putting manually for testing
let results = []
TeamModel.find( name: team )
.exec(async (err, docs) =>
if (err)
return res.send(Response("failure", "Error occured while retrieving fixtures"))
for(let i = 0; i < docs.length; i++)
let doesExist = await FixtureModel.exists( leagueName: docs[i].leagueName )
if (doesExist)
let query = FixtureModel.find( leagueName: docs[i].leagueName, $or: [ homeTeam: team , awayTeam: team ] )
await query.exec((err2, docs2) =>
if (err2)
return res.send(Response("failure", "Error occured while retrieving fixtures"))
docs2.forEach((doc2, index) => results.push(doc2.toObject()))
console.log('during await') //Executes second
)
console.log('after await') //Executes first
else //This section is not required
let result = await Communicator.GetFixturesFromLeague(docs[i].leagueId)
result.api.fixtures.forEach((fixture, index) =>
let newFixture = new FixtureModel(
fixtureId: fixture.fixture_id,
leagueId: fixture.league_id,
leagueName: fixture.league.name,
eventDate: fixture.event_date,
statusShort: fixture.statusShort,
homeTeam: fixture.homeTeam.team_name,
awayTeam: fixture.awayTeam.team_name
)
newFixture.save()
results.push(newFixture.toObject())
)
console.log(results)
res.send(Response("success", "Retrieved fixtures", results))
)
结果看起来像这样:
after await
[]
during await
因此,在向其中添加值之前会发送一个空的结果数组。我不确定我在这里缺少什么。
【问题讨论】:
因为当query.exec
承诺被解决时代码继续,而不是在回调完成执行时。尝试return docs2.forEach((doc2, index) => results.push(doc2.toObject()))
或docs2 = await query.exec()
然后docs2.forEach...
@dikuw 我怀疑可能是这种情况。尝试了您的解决方案,但仍然无效
query.exec()
仅在未通过回调时返回 Promise。
【参考方案1】:
如果有人想知道,这是一种解决方法。当 forLoop 完成绕过 async/await 的需要时,在 exec() 回调中发送响应。
if (doesExist)
let query = FixtureModel.find( league_name: docs[i].leagueName, $or: [ homeTeam: team_name: team , awayTeam: team_name: team ] )
await query.exec((err2, docs2) =>
if (err2)
return res.send(Response("failure", "Error occured while retrieving fixtures"))
docs2.forEach((doc2, index) => results.push(doc2.toObject()))
if(i + 1 == docs.length)
return res.send(Response("success", "Retrieved fixtures", results))
)
【讨论】:
恢复到计划 A 并写let docs2 = await FixtureModel.find(.......).exec();
并将 res.send(Response('success', 'Retrieved fixtures', results));
留在 for
循环之外的麻烦更少。同样,let docs = await TeamModel.find( 'name': team ).exec();
.
这两个 await 可以正常工作,您可以输入try /* everything */ catch(error) res.send(Response('failure', 'Error occurred while retrieving fixtures'));
。这将捕获/处理意外错误,而不仅仅是当前代码中的这两个特定错误。以上是关于Mongoose exec() 没有正确等待的主要内容,如果未能解决你的问题,请参考以下文章
Mongoose 中的 Model.findById() - 异步/等待 [重复]
countDocuments Mongoose 的问题:它实际上并没有等待回调函数执行
Mongoose - find(,cb) 和 find().exec(cb) 有啥区别?
Mongoose:“.find(...).exec(...).then(...).catch(...).finally 不是函数”使用蓝鸟?