递归Promise.all在Firebase中具有快照

时间:2018-08-17 01:21:27

标签: javascript firebase firebase-realtime-database promise es6-promise

我的Firebase数据库具有以下结构:

enter image description here

我需要获取键pin的值。为此,我正在使用这样的递归函数:

let pins = [];

const normalize = (snapchot) => {
  snapchot.forEach(function(child) {
    if(child.val().pin) {
      pins.push(Promise.resolve(child.val().pin));
    }
    else normalize(child);
  });
  return Promise.all(pins);
}

现在,调用normalize函数:

normalize(snapshot) // snapshot represents the data from the firebase db
  .then(p => {
    console.log(p); // [ 'mi-pin-agosto', 'mi-pin-julio' ]
  })
  .catch(err => {
    // handle error
  })

它可以工作,但是当我调试该代码时,我发现return Promise.all(pins);被调用了多次。 foreach完成后,我只需要被叫一次;这就是性能方面的想法,因为snapshot数据比我在图像中看到的要大。

任何想法???

1 个答案:

答案 0 :(得分:2)

仅在将 recursive 函数用作“ inside”`normalize

函数时,才使用Promise.all
const normalize = (snapshot) => {
    const process = x => {
        let ret = [];
        x.forEach(function(child) {
            if(child.val().pin) {
                ret.push(Promise.resolve(child.val().pin));
            } else {
                ret = ret.concat(process(child));
            }
        });
        return ret;
    });
    return Promise.all(process(snapshot));
}

此代码也不需要global数组来存储结果

但是,由于您要调用的任何代码都没有asynchronous,因此省去了normalize内的承诺

const normalize = (snapshot) => {
    let ret = [];
    snapshot.forEach(function(child) {
        if(child.val().pin) {
            ret.push(child.val().pin);
        } else {
            ret = ret.concat(normalize(child));
        }
    });
    return ret;
};

如果您确实需要对此代码使用Promises,则只需

Promise.all(normalize(snapshot))
.then(p => {
    console.log(p); // [ 'mi-pin-agosto', 'mi-pin-julio' ]
 })
.catch(err => {
    // handle error
})