例如,我有一个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',
}
]
}
我想要得到的是一组按类别分组的项目,例如:
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',
},
]
},
]
我使用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
})
}
}
在大多数情况下 ,效果很好。
在forEach
循环中,我将按类别检索数据,并实际上调度多个 partial itemList
,直到forEach
循环结束。
显然,我希望等到循环结束然后分派完整的itemList
。
我不知道如何等待循环结束-以及所有要解决的调用。
我觉得我应该与Promise
合作,但不确定如何实现。
答案 0 :(得分:1)
如何使用Promise.all()?
而不是在firebase.database().ref('items').orderByChild('categoryId').equalTo(categoryId).on
中触发调度
您可以将此调用添加到promises数组中。像这样:
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
})