当前位置: 首页 > 知识库问答 >
问题:

开火。解析所有嵌套promise后的all()

孔和畅
2023-03-14

我试图使用他们的Firebase API递归获取黑客新闻故事的所有评论。一个故事有一个孩子属性,它是一个表示注释的ID数组。每个注释都可以有自己的子属性,该属性指向其子注释,等等。我想创建整个注释树的数组,看起来像:

[{
  '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()。然后()在第一级注释promise解决后触发(这是有意义的,因为所有的注释promise都解决了。)然而,我想知道一旦所有嵌套的promise都解决了。我该怎么做呢?

共有2个答案

沃博裕
2023-03-14

小鬼:请参考torazaburo的回答。它比我的好多了。

=========

我认为这应该奏效:

function getItem(id) {
    return new Promise(function(resolve, reject) {
        api
        .child(`item/${id}`)
        .once('value')
        .then((snapshot) => {  // this is a Firebase Promise
            let val = snapshot.val()

            if (val.kids) {
                let replies = val.kids.map((id) => getItem(id))
                Promise.all(replies).then(replies => {
                    val.replies = replies // <<<<<< try this
                    resolve(val) // we want to resolve val, not val.replies
                }, err =>{
                    reject(err)
                })
            } else {
                resolve(val)
            }
        })
        .catch((err) => { // if there was some error invoking api call we need to reject our promise
            reject(err);
        })
    }
}

编辑:设置val.repress内部然后

章涵容
2023-03-14

没有必要像在其他答案中那样做出包装promise;这就是“显式promise构造函数反模式”。进一步简化,您可以执行以下操作:

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; 
        });
      );
    });
}

也不需要任何明确的拒绝处理。拒绝会自然地传播到顶层(假设这是您想要的)。

 类似资料:
  • 问题内容: 我必须与API进行交互,并且响应格式(根据我的阅读)似乎结构不良。我发现一个Google 网上论坛在这里回答了一个类似的问题,但是我在实现Response类来处理Gson.fromJson时遇到了麻烦。有没有我想念的例子? 问题答案: JSON对象可以由或Javabean类表示。这是一个使用Javabean的示例。 如下使用它:

  • 对于“航班”组合应用程序,我正在尝试为飞机上的每个座位生成机票(以便航班预先填充一些人)。这是一个功能的一部分,该功能还将航班预先填充到数据库以设置数据。有对数据库的调用,以检查航班号和确认号是否是唯一的,而不是预先存在的。在航班的情况下,如果航班号已经存在,则该航班将被删除。但是,如果确认号处于循环状态时已经存在,则重新生成确认号的异步方面遇到了一些问题。所以本质上,我遇到的问题: Genera

  • 我不熟悉promise和使用NodeJS中的请求和promise编写网络代码。 我想删除这些嵌套的promise,并将它们链接起来,但我不确定该如何做/这是否是正确的方式。 这是请求代码: 如有任何见解,将不胜感激。

  • 所以我有一个情况,我有多个未知长度的promise链。我希望在处理完所有链后运行一些操作。这可能吗?这里有一个例子: 在本例中,我为promise一、promise二和promise三设置了一个,这些promise将在某个随机时间得到解决。然后,我在第一和第三段的末尾加上promise。我希望在解析所有链后解析。以下是我运行此代码时的输出: 有没有办法等待锁链解决?

  • 问题内容: 此JSON输出来自MongoDB聚合查询。我本质上需要将嵌套数据JSON解析为以下’ 和值。 我尝试了5种不同的技术来从中获得所需的信息,但是使用和模块却遇到了问题。 理想情况下,输出将是这样的: 问题答案: 注意:来自MongoDB的JSON响应实际上无效。JSON需要双引号(),而不是单引号()。 我不确定为什么您的响应中有单引号而不是双引号,但是从其外观上,您可以替换它们,然后只

  • 问题内容: 我正在尝试解析这种结构:(它使我发疯,并且我尝试了我能想到的一切。但是我不是很有经验) “ topDrop”就像文件名吗?player是一个JSONArray,包含5个播放器JSONObject。但是在JSON术语中,最重要的是什么。我在JSON验证程序上签出有效的凭证,我需要这样的凭证: topDrop作为JSONObject Player,作为JSONArray,并循环遍历数组中的