简体   繁体   English

React-native-firebase数据库-从嵌套调用中检索数据

[英]React-native-firebase Database - Retrieve datas from nested calls

I have a Firebase database as such (for instance): 我有这样的Firebase数据库(例如):

{
    'itemCategories': [
        _categoryKey1: {
            name: 'Category 1'
        },
        _categoryKey2: {
            name: 'Category 2'
        },
        _categoryKey3: {
            name: 'Category 3'
        },
    ],
    'items': [
        _itemKey1: {
            categoryId: '_categoryKey1',
            name: 'Item 1',
        }
        _itemKey2: {
            categoryId: '_categoryKey2',
            name: 'Item 2',
        }
        _itemKey3: {
            categoryId: '_categoryKey1',
            name: 'Item 3',
        }
        _itemKey4: {
            categoryId: '_categoryKey3',
            name: 'Item 4',
        }
        _itemKey5: {
            categoryId: '_categoryKey3',
            name: 'Item 5',
        }
    ]
}

What I want to get is an array of items grouped by categories, as such: 我想要得到的是一组按类别分组的项目,例如:

itemList = [
    {
        category: 'Category 1',
        items: [
            {
                id: '_itemKey1',
                categoryId: '_categoryKey1',
                name: 'Item 1',
            },
            {
                id: '_itemKey3',
                categoryId: '_categoryKey1',
                name: 'Item 3',
            }
        ]
    },
    {
        category: 'Category 2',
        items: [
            {
                id: '_itemKey2',
                categoryId: '_categoryKey2',
                name: 'Item 2',
            }
        ]
    },
    {
        category: 'Category 3',
        items: [
            {
                id: '_itemKey4',
                categoryId: '_categoryKey3',
                name: 'Item 4',
            },
            {
                id: '_itemKey5',
                categoryId: '_categoryKey3',
                name: 'Item 5',
            },
        ]
    },
]

I use a react-redux action to achieve this, like so: 我使用react-redux动作来实现这一点,就像这样:

export const setItemList = (list) => {
    return {
        type: 'setItemList',
        value: list
    }
}

export const getItemListByCategory = () => {
    return (dispatch) => {

        let itemList = []

        firebase.database().ref('itemCategories').on('value', (snapCategory) => {
            snapCategory.forEach((category) => {
                const categoryId = category.key

                firebase.database().ref('items').orderByChild('categoryId').equalTo(categoryId).on('value', (snapItem) => {
                    let items = []
                    snapItem.forEach((item) => {
                        items.push({
                            id: item.key,
                            ...item.val()
                        })
                    })

                    itemList.push({
                        category: category.val().name,
                        items: items
                    })

                    // This is where I think is the issue
                    dispatch(setItemList(itemList))
                })
            })

            // The dispatch should be there, when every calls resolved
        })
    }
}

This works pretty well, for the most part . 在大多数情况下 ,这效果很好。 As I'm in a forEach loop, I will retrieve datas category by category, and actually dispatch multiple partial itemList until the forEach loop ends. 当我处于forEach循环中时,我将按类别检索数据,并实际上分派多个部分 itemList直到forEach循环结束。 Obviously, I'd prefer to wait until the loop ends then dispatch the complete itemList . 显然,我宁愿等到循环结束调度完整的itemList

I can't figure out how to wait for the loop to end - and all the calls to resolve. 我不知道如何等待循环结束-以及所有要解决的电话。 I feel like I should work with Promise but I'm not sure how to achieve it. 我觉得我应该与Promise但是我不确定如何实现它。

How about using Promise.all()? 如何使用Promise.all()? Instead of triggering dispatch in firebase.database().ref('items').orderByChild('categoryId').equalTo(categoryId).on You could add this call to a promises array. 除了可以在firebase.database().ref('items').orderByChild('categoryId').equalTo(categoryId).on中触发调度外,您还可以将此调用添加到promises数组中。 Something like this: 像这样:

const promises = [];

snapCategory.foreach(snap => {

   promises.push(your calls here, instead of dispatch return the list here)
}) 

Promise.all(promises).then((...args) => {
// args should contain all lists here, you can manipulate them as you need
// and dispatch afterwards
})

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

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