Рекурсивный Promise.all со снимком в Firebase

У меня есть следующая структура в моей базе данных Firebase:

введите описание изображения здесь

Мне нужно получить значения ключей 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 ответ

Решение

Использовать только 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
})
Другие вопросы по тегам