我正试图获取一些团体及其信息。 我需要加入firebase才能在每次群聊中获取最新消息。我已经开始工作了。 现在,我还必须从Firebase存储中获取Group-Image Url。我正在尝试使用Promise和.then()在Promise解决后继续进行。
我的想法是,对于每个组,它将使用带有groupId的getGroupImages()函数来获取图像。一旦有了图像,就会触发.then()中的代码。
这是我的代码以及我要执行的操作:
export const getUserGroups = () => {
return (dispatch) => {
dispatch({ type: GET_USERS_GROUPS });
const uid = firebase.auth().currentUser.uid;
firebase.database().ref(`/userGroups/${uid}/`)
.on('value', snapshot => {
const promises = [];
snapshot.forEach(child => {
const children = child.val();
const groupId = children.groupId;
getGroupImages(groupId).then((image) => {
children.image = image;
const promise = firebase
.database()
.ref(`/groups/${groupId}/lastmessage`)
.once('value')
.then(snap => {
children.lastmessage = snap.val();
return children;
});
promises.unshift(promise);
})
.catch((e) => console.log(e));
});
Promise.all(promises)
.then(groupArr => {
dispatch({ type: GET_USERS_GROUPS_SUCCESS, payload: groupArr });
})
.catch((e) => console.log(e));
});
};
};
这是我写的getGroupImages()函数:
const getGroupImages = (groupId) => {
return new Promise(() => (resolve, reject) => {
const ref = firebase.storage().ref(`images/${groupId}/groupImg`);
ref.getDownloadURL()
.then((image) => {
resolve(image);
})
.catch((e) => reject(e));
})
.catch((err) => console.log(err));
};
我对使用诺言很陌生,我正在尝试学习诺言,但在这里我真的不知道自己在做错什么。
EDIT2:* 我有一些工作要做,但我认为我创造了一个怪物。我不认为这应该是这样:
export const getUserGroups = () => {
return (dispatch) => {
dispatch({ type: GET_USERS_GROUPS });
const uid = firebase.auth().currentUser.uid;
firebase.database().ref(`/userGroups/${uid}/`)
.on('value', snapshot => {
const promises = [];
const groupArr = [];
const messages = [];
snapshot.forEach(child => {
const children = child.val();
const groupId = children.groupId;
const promise = getGroupImages(groupId)
.then(url => {
children.img = url;
return children;
})
.catch(e => console.log(e));
promises.unshift(promise);
}); // </foreach>
Promise.all(promises)
.then(children => { // child === array with both objects
const messages = [];
children.map(child => {
const groupId = child.groupId;
const ch = child;
const message = getLastMessages(groupId)
.then(msg => {
ch.lastMsg = msg;
return ch;
})
.catch((e) => console.log(e));
messages.unshift(message);
}); // .map
Promise.all(messages)
.then((bla) => {
dispatch({ type: GET_USERS_GROUPS_SUCCESS, payload: bla });
});
});
});
};
};
编辑1 在“ harshiL shah”的帮助下,我成功实现了诺言。但是,即使有许诺返回的图像,groupArr仍然为空。
snapshot.forEach(child => {
const children = child.val();
const groupId = children.groupId;
getGroupImages(groupId).then((image) => {
console.log(image); // url is showing
children.image = image;
const promise = firebase
.database()
.ref(`/groups/${groupId}/lastmessage`)
.once('value')
.then(snap => {
children.lastmessage = snap.val();
return children;
});
promises.unshift(promise);
});
});
Promise.all(promises)
.then(groupArr => {
console.log('groupArr');
console.log(groupArr); // [] empty Array
dispatch({ type: GET_USERS_GROUPS_SUCCESS, payload: groupArr });
})
答案 0 :(得分:1)
你过去了
() => (resolve, reject) => { some code }
在承诺中,实际上是
function() {
return function(resolve, reject) {
some code
}
}
实际上需要做的是
function(resolve, reject) {
some code
}
即(resolve, reject) => { some code }
请改用以下代码。
const getGroupImages = (groupId) => {
return new Promise((resolve, reject) => {
const ref = firebase.storage().ref(`images/${groupId}/groupImg`);
ref.getDownloadURL()
.then((image) => {
resolve(image);
})
.catch((e) => reject(e));
})
.catch((err) => console.log(err));
};
这是我可以在您的代码中找到的唯一问题。我本来会对此发表评论,但是我没有足够的声誉。
--------------进行新修改的答案----------------
要了解该问题,请说从Firebase获取图像需要1分钟的时间。 snapshot.foreach
甚至会在getGroupImages()
完成获取第一个图像之前完成其执行,只有在它进入之后,然后进行阻塞,并将获取消息的承诺添加到promises数组中。因此,在调用Promise.all(promises)
时,promises是一个空数组,然后在then块中得到空array(groupArr)。为了验证这一理论,您可以在Promise.all()
之前打印promise数组。
下面是在这种情况下应该起作用的修复程序。
snapshot.forEach(child => {
const children = child.val();
const groupId = children.groupId;
promise = getGroupImages(groupId)
.then((image) => {
children.image = image;
return firebase
.database()
.ref(`/groups/${groupId}/lastmessage`)
.once('value');
})
.then(snap => {
children.lastmessage = snap.val();
return children;
})
.catch((e) => console.log(e));
promises.unshift(promise);
});
我没有任何方法可以验证上面的代码是否正常工作。因此,请将其视为伪代码并进行必要的调整。