我正在使用Firebase进行项目,我遇到链接然后问题()。
我将关于用户的数据存储在对象中。 user的一个属性是对另一组名为events的数据的引用数组。我遍历引用以读取Firestore(Firebase数据库)中的数据并存储到我的本地对象'user'。
在打印用户对象时,首先显示第三个then()的输出语句。逻辑上每个应该在它之后执行,但第三个then()异步执行并首先打印输出。这是什么原因?此外,任何then()都没有返回任何值。这是问题的根源吗?
orgRef.collection('collection').doc('doc').get()
.then(function(data){
user.info = data.data();
})
.then(function(){
user.info.events.forEach(function(event){
eventRef.get()
.then(function(data){
user.eventdata[event] = data.data()[event];
})
.then(function(){
console.log(user);
});
});
})
.then(function(){
console.log('AT END');
console.log(user);
});
我添加了输出,每个console.log语句都打印相同的对象'user'。对象被打印三次,因为循环执行两次并打印对象。第三个是因为对主get()promise的then()语句。
AT END
{
eventdata: {}
}
{
eventdata:
{ FEENbYcy04k6XPR148rv:
//more data
}
}
{
eventdata:
{ FEENbYcy04k6XPR148rv:
//more data
622kUqbF9jftq1nKkQSb:
//more data
}
}
答案 0 :(得分:3)
您需要正确地链接承诺。因此,您的eventRef.get().then
未与您的最终'AT END'
相关联。
使用Promise.all
将一组承诺转换为一个承诺,然后为第三个then
返回该承诺。
orgRef.collection('collection').doc('doc').get()
.then(function(data) {
user.info = data.data();
})
.then(function() {
const allPromises = user.info.events.map(function(event) {
return eventRef.get()
.then(function(data) {
user.eventdata[event] = data.data()[event];
})
.then(function() {
console.log(user);
});
});
return Promise.all(allPromises);
})
.then(function() {
console.log('AT END');
console.log(user);
});
通过使用ES6箭头函数和隐式返回,你可以使它更加简洁:
orgRef.collection('collection').doc('doc').get()
.then(data => user.info = data.data())
.then(() => (
Promise.all(user.info.events.map((event) => (
eventRef.get()
.then(data => user.eventdata[event] = data.data()[event])
.then(() => console.log(user))
)))
))
.then(() => {
console.log('AT END');
console.log(user);
});
答案 1 :(得分:0)
因为这个原因,你的承诺没有回报任何价值:
.then(function(){
console.log(user);
});
此.then()
处理程序没有返回值,这使得promise的已解析值变为undefined
。您需要返回值:
.then(function(data){
console.log(data);
return data;
});