Javascript 在同一承诺内将用户和化身URL相互链接
我需要一些帮助。我从firebase收集所有用户,得到一个包含键值对的对象数组。我想向该对象添加另一个键值对:Javascript 在同一承诺内将用户和化身URL相互链接,javascript,reactjs,firebase,promise,Javascript,Reactjs,Firebase,Promise,我需要一些帮助。我从firebase收集所有用户,得到一个包含键值对的对象数组。我想向该对象添加另一个键值对: avatarUrl: 'someurl' 然后我想把它送到我的减速机上 我有点难以将两者结合起来,以下是我取得的成绩: const collectionRef = dbf.collection('users'); const collectionArray = []; collectionRef.get() .then((snapshot) => { s
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,
});
})
我有一个承诺中的一个承诺,但事情似乎并不顺利
有什么想法吗?让我们试试看
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)
通过为addDocIdAndAvatar
使用async
函数,我们可以等待avatarUrl
。类似地,在collectUsersFromSnapshot
中,我们首先使用addDocIdAndAvatar
映射快照中的用户集合,这是一个承诺,然后使用Promise。所有到等待将整个承诺集合解析为一个解析数组,然后将其传递到dispatch
如果您的设置禁止使用现代JS功能,如async
函数,则可以使用此等效的fluent版本:
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)
@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);
});
感谢您回答benny,我不熟悉async await(应该深入了解一下),不知怎的,我在await snapshot=>dispatch中遇到了一个complile错误({…….在这种情况下,您的构建步骤不支持异步函数,这是一个遗憾。我将制作一个使用流畅流的版本,请稍候。理解异步/await的唯一提示:异步函数返回一个承诺,await关键字是。然后
如果出现错误,try/catch
是。如果快照不是ar,则catch
ray,你如何得到一个forEach
实例方法?