【问题标题】:Loop through data to pull array of firebase values循环数据以提取 firebase 值数组
【发布时间】:2018-02-25 01:20:22
【问题描述】:

我有一个包含 N 条路径的数组,用于从 firebase 数据库中的不同位置检索数据。

searchPaths = ['locations/date1/imageID', 'locations/date2/imageID2', locations/date3/imageID3, ...]

现在,我想遍历每个搜索路径并从中提取一个值以保存图像 URL 数组。

    const searchPaths = ['locations/date1/imageID', 'locations/date2/imageID2']
    const imageURLs = []

     for(var Obj in searchPaths) 
    {
        const path = Obj
        admin.database().ref(path).once('value').then(snapshot => 
        { 
        const URL = snapshot.val().fileURL;
        imageURLs.push(URL);
        console.log('ImageURL: ' + URL );
        })
    // here is where it gets sour
    }.then(() => {
        console.log("All image URL's" + imageURLs")
    }

所以,我的问题是,当我们现在从每个 ref 中提取了我们需要的数据时,我该如何返回一个 Promise?有Promise.all 类型吗?去哪儿了?

【问题讨论】:

    标签: javascript firebase firebase-realtime-database google-cloud-functions


    【解决方案1】:

    您可以使用 for 循环创建一个 promise 数组,然后使用 Promise.all,我知道这很粗糙,但它应该可以工作。

    const searchPaths = ['locations/date1/imageID', 'locations/date2/imageID2']
    const imageURLs = []
    var promises = [];
     for(var Obj in searchPaths) 
    {
        promises.push(new Promise(function(resolve, reject) {
          const path = Obj
          admin.database().ref(path).once('value').then(snapshot => 
          { 
          const URL = snapshot.val().fileURL;
          imageURLs.push(URL);
          console.log('ImageURL: ' + URL );
    
          //resolve the promise after pushing imageURL
          resolve();
          })
        }));
    }
    
    //when all of them are done:
    Promise.all(promises)
    .then(function(results) {
      //code when done...
    })
    

    【讨论】:

    • Promise 对象具有三种状态:待处理、已解决和拒绝。任何Promise 对象都是用一个带有两个参数的函数构建的:resolve 和reject 函数。当resolve被调用时,promise会resolve,并返回一个值,和reject类似,但在reject的情况下会抛出一个错误。在这段代码中,我们实质上是让 Promise 处于“待处理”状态,直到我们在加载图像时调用 resolve 来解决 Promise。然后我们用这些 Promise 填充一个数组,然后在 Promise.all 中使用它们,等待所有 Promise 解决。
    • 这里有太多的工作要做。 once() 返回一个 Promise,所以不需要每次都创建一个新的 Promise 对象。请在此处查看我的答案以获得更短、更优雅的解决方案。
    【解决方案2】:

    这里的另一个答案是收集承诺太麻烦了。将 once() 的返回值推送到 Promise 数组中比每次都创建一个新的 Promise 更容易。

    const searchPaths = ['locations/date1/imageID', 'locations/date2/imageID2']
    const imageURLs = []
    const promises = []   // collect promises here
    
    searchPaths.forEach(path => {
        promises.push(admin.database().ref(path).once('value'))
    })
    
    Promise.all(promises).then(results => {
        results.forEach(snapshot => {
            const URL = snapshot.val().fileURL;
            imageURLs.push(URL);
            console.log('ImageURL: ' + URL );
        }
    })
    

    Promise.all() 返回的 Promise 上的 then 回调将是一个数组,其中包含来自推送到 promises 数组的查询的所有快照。

    【讨论】:

      猜你喜欢
      • 2023-02-25
      • 2017-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 2018-02-22
      • 1970-01-01
      相关资源
      最近更新 更多