【发布时间】:2019-12-12 16:40:59
【问题描述】:
我正在创建一个 NodeJS 后端,其中一个进程从源读取数据,检查与当前数据相比的更改,对 MongoDB 进行这些更新并报告所做的更改。一切正常,除了我无法报告更改,因为我无法等待 Mongoose 更新操作。
这个函数返回的数组然后由 Koa 服务器显示。它显示一个空数组,并且在服务器日志中,服务器返回空响应后会显示正确的值。
我已经深入研究了 Mongoose 文档和 Stack Overflow 问题——关于这个主题的很多问题——但没有成功。提供的解决方案似乎都没有帮助。我已将问题隔离到这一部分:如果我删除 Mongoose 部分,一切都会按预期工作。
const parseJSON = async xmlData => {
const changes = []
const games = await Game.find({})
const gameObjects = games.map(game => {
return new GameObject(game.name, game.id, game)
})
let jsonObj = require("../sample.json")
Object.keys(jsonObj.items.item).forEach(async item => {
const game = jsonObj.items.item[item]
const gameID = game["@_objectid"]
const rating = game.stats.rating["@_value"]
if (rating === "N/A") return
const gameObject = await gameObjects.find(
game => game.bgg === parseInt(gameID)
)
if (gameObject && gameObject.rating !== parseInt(rating)) {
try {
const updated = await Game.findOneAndUpdate(
{ _id: gameObject.id },
{ rating: rating },
{ new: true }
).exec()
changes.push(
`${updated.name}: ${gameObject.rating} -> ${updated.rating}`
)
} catch (error) {
console.log(error)
}
}
})
return changes
}
一切正常 - 找到更改并更新数据库,但报告的更改返回得太晚,因为执行不等待 Mongoose。
我也试过这个而不是findOneAndUpdate():
const updated = await Game.findOne()
.where("_id")
.in([gameObject.id])
.exec()
updated.rating = rating
await updated.save()
这里的结果相同:其他一切正常,但异步不起作用。
【问题讨论】:
-
猫鼬版本是什么?
-
Promise 不会被 forEach 等待,因为它是同步的。把你的承诺放在一个数组中,然后在上面做 Promise.all
-
@PuneetSharma Mongoose 5.5.8。看起来 forEach() 确实是这里的问题。
-
是的。换成
await Promise.all(jsonObj.items.item).map(async(item => {})) -
@krbalaji "Promise.all(...).map 不是函数"
标签: node.js mongodb mongoose async-await