【问题标题】:Nested Promise Function Using Firebase Database使用 Firebase 数据库的嵌套 Promise 函数
【发布时间】:2019-03-29 10:00:15
【问题描述】:

我有以下函数,它接受一个参数(“名称”数组),然后根据该数组检查每个用户的 firebase 数据库中的数据。

它使用它为每个用户及其电子邮件编译一个“设置”数组,以及用户与作为参数输入的列表共享的名称。函数如下所示。

fbDaemon = ({ folderNames }) => {
  const settings = [];
  ref.once("value")
    .then((snapshot) => {
      snapshot.forEach(user => {
        auth.getUser(user.key)
          .then(function(userRecord) {
            let email = userRecord.toJSON().email;
            let zips = [];

            user.forEach(setting => {
              let dep = setting.val().department;
              if(folderNames.includes(dep)){
                zips.push(dep);
              }
            });

            settings.push({ email, zips });
          })
          .catch(function(error) {
            console.log("Error fetching user data:", error);
          });
      });
  });
});

本质上,它会遍历我的整个数据库并编译我将传递给下一个函数的设置列表。最终结果应如下所示:

[ { email: 'example@example1.com',
    zips: [ 'Drug Enforcement Administration', 'Executive Branch' ] }, 
 { email: 'example@example2.com',
    zips: [ 'FEMA', 'Congress' ] },
];

我现在遇到的问题是我无法在适当的时间返回“设置”数组。

如何重新配置​​此函数,以便仅在整个函数运行后返回设置数组?

换句话说,我想用设置数组返回一个已解决的承诺。我该怎么做?

【问题讨论】:

    标签: javascript firebase firebase-realtime-database promise


    【解决方案1】:

    也许您可以在这里使用Promise.all() 来解析一组promise(其中数组中的每个项目对应于对该项目/用户的getUser 的调用)?

    所以,大致是这样的:

    fbDaemon = ({ folderNames, folderPaths }) => {
      const settings = [];
    
      return ref.once("value")
        .then((snapshot) => {
    
          // Collect all users from snapshot into an array
          const users = []
          snapshot.forEach(user => { users.push(user) })
    
          // Create promise for each user, and use Promise.all to 
          // resolve when each "user promise" is complete
          return Promise.all(users.map(user => {
    
            // Be sure to add "return" here
            return auth.getUser(user.key)
            .then(function(userRecord) {
              let email = userRecord.toJSON().email;
              let zips = [];
    
              user.forEach(setting => {
                let dep = setting.val().department;
                if(folderNames.includes(dep)){
                  zips.push(dep);
                }
              });
    
              settings.push({ email, zips });
            })
            .catch(function(error) {
              console.log("Error fetching user data:", error);
            })
          }));
      }).then(function() {
    
         return settings;
      });
    };
    

    【讨论】:

    • 两个注意事项:您应该返回原始承诺:return ref.once(...),还应该返回Promise.all.then中的设置数组:return Promise.all(...).then(() => { return settings; })
    • @CRice 感谢您的建议-刚刚修改了答案以捕获这些建议:)
    • 谢谢。永远不会想到这一点。一个简单的问题——为什么我们需要包含所有这些返回语句?他们究竟在这里完成了什么?
    • @HarryCramer 不客气 - 是的,这有点需要考虑。这里可以使用基于 async/await 的方法,它会使代码更清晰(选择基于 Promise 的方法以更好地匹配问题) - 您需要帮助吗?
    • @HarryCramer 没问题 - 这有帮助吗? gist.github.com/dacredenny/c2a202aba7cfaf375f2c5fe82899f6c5
    猜你喜欢
    • 1970-01-01
    • 2017-05-28
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-19
    • 2016-12-14
    • 2020-10-19
    相关资源
    最近更新 更多