gpt4 book ai didi

javascript - forEach 中的内部 Firestore promise 在外部 promise 之后执行

转载 作者:行者123 更新时间:2023-11-30 19:56:29 25 4
gpt4 key购买 nike

我正在使用 node.js 从 Firestore 中的 2 个不同集合中获取数据。

这个问题和这个类似,但是这个问题没有答案:Nested Firebase Firestore forEach promise queries

就我而言,我正在创建一个类似 Instagram 的应用程序,其中有一个“时间轴”集合。在时间线文档中,我有一个用户 key 。从该用户 key ,我想从“用户”集合中执行另一个查询。

从逻辑上讲,这里是查询步骤:

  1. 获取包含用户 key 的时间线数据(在数组中)。
  2. 使用该用户 key ,获取用户数据(单个数据)
  3. 向客户端返回 JSON 响应。

问题是,在获取用户数据之前返回了 JSON 响应。

这是我的代码:

tlRoute.get((req,res)=>{

//reading from firestore
let afs = req.app.get('afs');

var timelineArr = [];

let timelineRef = afs.collection(`timeline/${req.params.key}/timeline`);
timelineRef.get().then((snapshot) => {

snapshot.forEach((doc) => {

if(!doc.exists){
console.log('No such document!');
} else {

//populating timelineData with doc.data()
console.log('populating timelineData');
let timelineData = doc.data();

let userRef = afs.doc(`user/${doc.data().userKey}`);
userRef.get().then((doc) => {

//adding user details to timelineData
console.log('adding user details to timelineData');
timelineData.profileImageUrl = doc.data().profileImageUrl;
timelineData.username = doc.data().username;
timelineArr.push(timelineData);

});
}

});
})
.catch(err => {
console.log(err);
});

console.log('this is the final timelineArr', timelineArr);

//returning response json data to client
return res.json(timelineArr);

});

在控制台日志中,这是我得到的日志:

this is the final timelineArr []
populating timelineData
populating timelineData
adding user details to timelineData
adding user details to timelineData

如有任何帮助,我们将不胜感激。

最佳答案

我已尝试重构您的代码以产生相同的输出,添加了一些方法,每个方法都具有与特定类型对象相关的更简单、独立、可测试的目的。

// return a promise that resolves to a user doc snapshot with the given key
function getUserWithKey(db, userKey) {
return db.doc(`user/${userKey}`).get();
}

// return a promise that resolves to a timeline object augmented to include
// its doc id and its associated user's username
function timelineObject(db, timelineDocSnapshot) {
let timelineObject = timelineDocSnapshot.data();
timelineObject.postKey = timelineDocSnapshot.id;
return getUserWithKey(db, timelineObject.userKey).then(userDocSnapshot => {
timelineObject.username = userDocSnapshot.data().username;
timelineObject.profileImageUrl = userDocSnapshot.data().profileImageUrl;
return timelineObject;
});
}

// return a promise that resolves to all of the timeline objects for a given key
function getTimeline(db, key) {
let timelineRef = db.collection(`timeline/${key}/timeline`);
return timelineRef.get().then(querySnapshot => {
let promises = querySnapshot.docs.map(doc => timelineObject(db, doc));
return Promise.all(promises);
});
}

// get route for a timeline
tlRoute.get((req,res)=>{
let db = req.app.get('db');
let key = req.params.key;
return getTimeline(db, key).then(timelineObjects => {
return res.json(timelineObjects);
});
})

可以使用 async/await 语法进一步改进此代码。

关于javascript - forEach 中的内部 Firestore promise 在外部 promise 之后执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53932852/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com