Javascript,Redux thunk,同步/嵌套承诺
Javascript, Redux thunk, synchronous / nested promises
我有一个直接消息传递应用程序。所有数据都存储在 Firebase 中。每个聊天包含一组用户 ID。
我使用以下函数获取来自 componentDidMount()
的所有聊天记录:
return dispatch => new Promise(resolve => FirebaseRef.child('chats')
.on('value', snapshot => resolve(dispatch({
type: 'CHATS_REPLACE',
data: snapshot.val() || [],
})))).catch(e => console.log(e));
经过:
chatReducer(state = initialState, action) {
case 'CHATS_REPLACE': {
let chats = [];
if (action.data && typeof action.data === 'object') {
chats = Object.values(action.data).map(item => ({
id: item.id,
title: item.title,
authorizedUsers: Object.values(item.authorizedUsers).map(user => ({
id: user.id,
// Somedata: fetchUserData(user.id)
// -> pretty sure it can't be done here <-
})),
}));
}
return {
...state,
error: null,
loading: false,
chats,
};
我将如何从 users/:uid
的 Firebase 每次聊天中获取每个用户的更多数据?
我不知道这个有什么用。如果你能分享,比如你想使用多少关于用户的信息,那就太好了。如果它的数据很小,为什么不将它添加到同一个 API Only 中。您可以将用户数据传递到同一个对象中,并将用户 ID 作为键,并在嵌套数据中使用相同的键(仅当用户数据很小或者您知道 API 数据总是有限的,例如因为分页或页面大小。:
{
posts : [
{
title : 'abc'
authorizedUsers : ['1a', '2b', '3c']
}, ....
],
users : {
'1a' : {
name : 'john doe',
profileImage : 'https://some.sample.link',
},
'2b' : {
name : 'bob marshal',
profileImage : 'https://some.sample.link2',
}
}
}
如果数据很大或无法添加到 API 中(因为 API 归第 3 方所有),那么您只能放置代码,而不仅仅是调度操作收到响应后,仅在您的服务中循环响应,进行异步调用以仅获取所有“唯一用户”,将该数据附加到您从上一个 api 调用,然后将具有完整数据的操作分派到商店。这可能不是最好的方法,因为一切都必须停止,即即使在 1st api 中收到的数据也会停止(不在屏幕上更新),直到获取所有用户数据。但是只有在我们了解有关用例的更多详细信息后才能给出最佳解决方案。就像最终用户滚动屏幕时可能会懒惰地获取用户数据,并且可能会看到特定的 post 或者一旦您从第一个 API 调用开始呈现数据就获取用户详细信息,例如制作一个用于显示用户关联的组件使用 post 并在其 componentDidMount 中,您将 userIds 作为道具从可能是 "article/post/blog" 组件的顶级组件传递,并且它在实际呈现 "article/blog/post" 时获取数据。
希望对您有所帮助。
我有一个直接消息传递应用程序。所有数据都存储在 Firebase 中。每个聊天包含一组用户 ID。
我使用以下函数获取来自 componentDidMount()
的所有聊天记录:
return dispatch => new Promise(resolve => FirebaseRef.child('chats')
.on('value', snapshot => resolve(dispatch({
type: 'CHATS_REPLACE',
data: snapshot.val() || [],
})))).catch(e => console.log(e));
经过:
chatReducer(state = initialState, action) {
case 'CHATS_REPLACE': {
let chats = [];
if (action.data && typeof action.data === 'object') {
chats = Object.values(action.data).map(item => ({
id: item.id,
title: item.title,
authorizedUsers: Object.values(item.authorizedUsers).map(user => ({
id: user.id,
// Somedata: fetchUserData(user.id)
// -> pretty sure it can't be done here <-
})),
}));
}
return {
...state,
error: null,
loading: false,
chats,
};
我将如何从 users/:uid
的 Firebase 每次聊天中获取每个用户的更多数据?
我不知道这个有什么用。如果你能分享,比如你想使用多少关于用户的信息,那就太好了。如果它的数据很小,为什么不将它添加到同一个 API Only 中。您可以将用户数据传递到同一个对象中,并将用户 ID 作为键,并在嵌套数据中使用相同的键(仅当用户数据很小或者您知道 API 数据总是有限的,例如因为分页或页面大小。:
{
posts : [
{
title : 'abc'
authorizedUsers : ['1a', '2b', '3c']
}, ....
],
users : {
'1a' : {
name : 'john doe',
profileImage : 'https://some.sample.link',
},
'2b' : {
name : 'bob marshal',
profileImage : 'https://some.sample.link2',
}
}
}
如果数据很大或无法添加到 API 中(因为 API 归第 3 方所有),那么您只能放置代码,而不仅仅是调度操作收到响应后,仅在您的服务中循环响应,进行异步调用以仅获取所有“唯一用户”,将该数据附加到您从上一个 api 调用,然后将具有完整数据的操作分派到商店。这可能不是最好的方法,因为一切都必须停止,即即使在 1st api 中收到的数据也会停止(不在屏幕上更新),直到获取所有用户数据。但是只有在我们了解有关用例的更多详细信息后才能给出最佳解决方案。就像最终用户滚动屏幕时可能会懒惰地获取用户数据,并且可能会看到特定的 post 或者一旦您从第一个 API 调用开始呈现数据就获取用户详细信息,例如制作一个用于显示用户关联的组件使用 post 并在其 componentDidMount 中,您将 userIds 作为道具从可能是 "article/post/blog" 组件的顶级组件传递,并且它在实际呈现 "article/blog/post" 时获取数据。
希望对您有所帮助。