需要一些帮助。从firebase,我收集了所有用户,得到了一个包含键值对的对象数组。我要向该对象添加另一个键值对:
avatarUrl: 'someurl'
然后我想将其发送给我的减速器。
我很难将两者结合起来,这是我取得的成就:
const collectionRef = dbf.collection('users');
const collectionArray = [];
collectionRef.get()
.then((snapshot) => {
snapshot.forEach((doc) => {
let withId = {
docId: doc.id,
...doc.data(),
};
collectionArray.push(withId);
storageRef.child(`${doc.id}/avatar.jpg`).getDownloadURL().then((url) => {
withId = {
...withId,
avatarUrl: url,
};
collectionArray.push(withId);
});
});
return dispatch({
type: actionTypes.DONE,
data: collectionArray,
});
})
我在一个诺言中有一个诺言,而事情似乎进展不顺利。
有什么想法吗?
答案 0 :(得分:1)
让我们尝试一下
const collectionRef = dbf.collection('users');
const storageRef = /*...*/
// getAvatarUrl :: String -> Promise String
const getAvatarUrl = userId =>
storageRef
.child(`${userId}/avatar.jpg`)
.getDownloadURL()
// addDocIdAndAvatar :: Doc -> Promise {docId, ...docData, avatarUrl}
const addDocIdAndAvatar = async doc => ({
docId: doc.id,
...doc.data(),
avatarUrl: await getAvatarUrl(doc.id)
});
// collectUsersFromSnapshot :: Snapshot -> Dispatch
const collectUsersFromSnapshot = await snapshot =>
dispatch({
type: actionTypes.DONE,
data: await Promise.all(snapshot.map(addDocIdAndAvatar)),
});
collectionRef.get()
.then(collectUsersFromSnapshot)
通过对async
使用addDocIdAndAvatar
函数,我们可以await
avatarUrl
。同样,在collectUsersFromSnapshot
中,我们首先使用addDocIdAndAvatar
(一个承诺)映射快照中的用户集合,然后使用Promise.all
来await
解析整个承诺集合解析度数组,然后传递给dispatch
。
如果您的设置禁止使用诸如async
函数之类的现代JS功能,则可以使用以下等效的流畅版本:
const collectionRef = dbf.collection('users');
const storageRef = /*...*/
// getAvatarUrl :: String -> Promise String
const getAvatarUrl = userId =>
storageRef
.child(`${userId}/avatar.jpg`)
.getDownloadURL()
// addDocIdAndAvatar :: Doc -> Promise {docId, ...docData, avatarUrl}
const addDocIdAndAvatar = doc =>
getAvatarUrl(doc.id)
.then(avatarUrl => ({ docId: doc.id, ...doc.data(), avatarUrl }))
// dispatchUsers :: [User] -> Dispatch
const dispatchUsers = data =>
dispatch({ type: actionTypes.DONE, data })
// collectUsersFromSnapshot :: Snapshot -> Promise Dispatch
const collectUsersFromSnapshot = snapshot =>
Promise.all(snapshot.map(addDocIdAndAvatar))
.then(dispatchUsers)
collectionRef.get()
.then(collectUsersFromSnapshot)
答案 1 :(得分:0)
@BennyPowers谢谢,由于您的代码,我设法解决了它。快照不是数组,用户数组仅在创建集合数组之后形成。因此必须对其进行一些更改,但最终结果是:这对于asnyc开发有意义吗?
const collectionRef = dbf.collection('users');
const collectionArray = [];
collectionRef.get()
.then((snapshot) => {
snapshot.forEach((doc) => {
let withId = {
docId: doc.id,
...doc.data(),
};
collectionArray.push(withId);
storageRef.child(`${doc.id}/avatar.jpg`).getDownloadURL().then((url) => {
withId = {
...withId,
avatarUrl: url,
};
collectionArray.push(withId);
});
});
const getAvatarUrl = userId => storageRef
.child(`${userId}/avatar.jpg`)
.getDownloadURL();
const addDocIdAndAvatar = doc => getAvatarUrl(doc.docId)
.then(avatarUrl => ({ ...doc, avatarUrl }));
const dispatchUsers = data => dispatch({ type: actionTypes.DONE, data });
Promise.all(collectionArray.map(addDocIdAndAvatar))
.then(dispatchUsers);
});