作者:lanshan1126141 | 来源:互联网 | 2023-02-13 17:20
我正在尝试使用他们的Firebase API以递归方式获取Hacker News故事的所有评论.故事有一个kids
属性,它是一组代表注释的ID.每个注释都可以有自己的kids
属性,指向其子注释,依此类推.我想创建一个整个注释树的数组,看起来像这样:
[{
'title': 'comment 1',
'replies': [{
'title': 'comment 1.1'
}, {
'title': 'comment 1.2'
'replies': [{
'title': 'comment 1.2.1'
}]
}]
}]
我以为我可以使用以下功能执行此操作:
function getItem(id) {
return api
.child(`item/${id}`)
.once('value')
.then((snapshot) => { // this is a Firebase Promise
let val = snapshot.val()
if (val.kids) {
val.replies = val.kids.map((id) => getItem(id))
}
return val
})
}
然后在使用以下内容获取整个评论树后收到通知:
getItem(storyId)
.then(story => {
// The story and all of its comments should now be loaded
console.log(story)
})
Promise.all().then()
一旦第一级评论承诺得到解决,最终发生的事情就是火灾(这是有道理的,因为所有commentPromises
已经解决了.)但是,我想知道一旦所有嵌套的承诺都解决了.我怎样才能做到这一点?
1> 小智..:
在其他答案中不需要包装器承诺; 这就是" 显式承诺构造函数反模式 ".简化一点,您可以执行以下操作:
function getItem(id) {
return api
.child(`item/${id}`)
.once('value')
.then(snapshot => {
const val = snapshot.val();
return Promise.all((val.kids || []).map(getItem))
.then(kidsVals => {
val.replies = kidsVals;
return val;
});
);
});
}
也不需要任何明确的拒绝处理.拒绝会自然地传播到顶层(假设这是你想要的).