繁体   English   中英

在映射数组时将异步函数的结果包含在我的“返回”中

[英]Including the results of an async function in my 'return' while mapping an array

问题

我试图在映射数组时调用数据库函数。 我创建了一些示例代码来在较小的范围内演示我的问题。 我正在使用 'mysql2' 和 'sequelize' 依赖项,以及 MySQL Workbench。

示例代码中的目标

我的数据库中有两个表——一个叫做“boxes”,一个叫做“items”。 每个项目都将在一个框中(它将具有“box_id”的属性)。 每个盒子都有一个位置。 我想得到一个对象数组,它只显示项目的名称和它所在的盒子的位置(不仅仅是 ID)。 我希望它以最干净的方式运行。 我知道有一种方法可以将这两个数据库联系在一起,并且我会很感激如何做到这一点,但我觉得我会使用不同的方法学习更重要的概念 - 所以理想情况下,我想要一个替代解决方案。

代码

mainFunction() 是起点

// Gets all items currently in my database and returning the dataValues
const getAllItems = async () => {
    const findAllItems = await Item.findAll()
    const items = findAllItems.map(item => item.dataValues)
    return items
}

// Gets a box from my database, by ID, and returning its dataValues
const getOneBox = async (id) => {
    const findOneBox = await Box.findOne({ where: {id}})
    return findOneBox.dataValues
}

// Starting point
const mainFunction = async () => {
// Get all items in database
    const items = await getAllItems()

// Go through each item, and everytime, get the box that corresponds to the item's box_id
    const myArray = 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
        }
    })

// The function will only work if I manually give my function enough time to finish
    console.log('myArray before delay => ', myArray)
    await new Promise(response => setTimeout(response, 500))
    console.log('myArray after delay => ', myArray)
}

这是我终端中的结果:

在此处输入图片说明

设置

如果重要的话,这是我的设置。 我手动填充了我的表格以简化事情:

项目 => 物品

盒子 => 盒子

// Populating the existing 'test' schema with relevant tables and running main function after connecting
const Sequelize = require('sequelize')
const database = new Sequelize ('test', 'root', [REDACTED], {
    host: 'localhost',
    dialect: 'mysql',
    define: {
        timestamps: false
    }
})
const connect = async () => {
    await database.authenticate()
    .then(async () => {
        await database.sync()
        console.log('Connected...')
        mainFunction()
    }).catch(error => {
        console.log('Failed to connect => ', error)
    })
}
connect()


// Defining my models
const Box = database.define('box', {
    name: Sequelize.STRING,
    location: Sequelize.STRING
})
const Item = database.define('item', {
    name: Sequelize.STRING,
    box_id: Sequelize.INTEGER
})

原来问题出在我的方法上; 使用 for 循环实际上很容易。 我会留下我的解决方案,以防它对任何人有帮助。

这个只是向我的 items 数组添加了另一个属性

const mainFunction = async () => {
    const items = await getAllItems()
    for(i = 0; i < items.length; i++) {
        const getBox = await getOneBox(items[i].box_id)
        items[i]['location'] = getBox.location
    }
    console.log(items)
}

在此处输入图片说明

这个是为了如果我想以我自己的方式格式化它

const mainFunction = async () => {
    const items = await getAllItems()
    const itemsFormatted = []
    for(i = 0; i < items.length; i++) {
        const getBox = await getOneBox(items[i].box_id)
        itemsFormatted.push({
            itemID: items[i].id,
            itemName: items[i].name,
            itemLocation: getBox.location
        })
    }
    console.log(itemsFormatted)
}

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM