数组map遍历调用Sequelize异步查询时如何正确获取返回结果?
问题原因
你在Array.map()中传入异步函数,每个迭代都会返回一个Pending状态的Promise,所以直接拿到的是Promise数组,手动加延迟完全依赖网络和数据库响应速度,生产环境随时会出问题。
方案1:不使用表关联的标准实现(符合你学习核心概念的需求)
只需要修改mainFunction的遍历部分,用Promise.all等待所有异步查询完成即可:
const mainFunction = async () => { // Get all items in database const items = await getAllItems() // 用Promise.all等待所有异步查询box的任务执行完成 const myArray = await Promise.all(items.map(async item => { const getBox = await getOneBox(item.box_id) // Return an object with my custom formatting, and including the box's location return { itemID: item.id, itemName: item.name, itemLocation: getBox.location } })) // 这里直接就能拿到结果,不需要任何延迟 console.log('myArray最终结果 => ', myArray) }
性能优化建议
上面的写法每个item都要发一次数据库查询请求,item数量多的时候性能很差,可以优化为批量查询所有需要的box再做匹配,全程只需要两次数据库请求:
const mainFunction = async () => { const items = await getAllItems() // 先提取所有需要查询的box_id,去重后批量查询 const boxIds = [...new Set(items.map(item => item.box_id))] const boxes = await Box.findAll({ where: { id: boxIds } }) // 把box转成id为键的Map,方便快速匹配 const boxMap = new Map(boxes.map(box => [box.id, box.dataValues])) // 同步匹配即可,不需要多次异步查询 const myArray = items.map(item => ({ itemID: item.id, itemName: item.name, itemLocation: boxMap.get(item.box_id).location })) console.log('最终结果 => ', myArray) }
方案2:Sequelize关联查询(生产环境最优方案)
先定义两个模型的关联关系,一次查询就能拿到所有需要的数据,不需要自己做额外逻辑处理:
// 关联关系写在模型定义之后即可 Item.belongsTo(Box, { foreignKey: 'box_id', as: 'box' }) Box.hasMany(Item, { foreignKey: 'box_id' }) // 之后直接关联查询即可 const mainFunction = async () => { const items = await Item.findAll({ include: [{ model: Box, as: 'box', attributes: ['location'] // 只查询需要的location字段,减少数据传输 }] }) const myArray = items.map(item => ({ itemID: item.id, itemName: item.name, itemLocation: item.box.location })) console.log('最终结果 => ', myArray) }
内容的提问来源于stack exchange,提问作者easymoney
相关产品推荐
相关产品推荐

