Ожидание завершения всех вызовов firebase с помощью функции map - PullRequest
0 голосов
/ 05 февраля 2019

Я получаю свои данные пользователя, и функция карты вызывается несколько раз для каждого пользователя.Я хочу подождать, пока все данные не будут помещены в массив, а затем манипулировать данными.Я пытался использовать Promise.all (), но это не сработало.Как я могу дождаться завершения этой функции карты, прежде чем продолжить?

Нет необходимости говорить, что массив user_list_temp пуст при печати внутри Promise.all ().

 const phone_list_promise_1 = await arrWithKeys.map(async (users,i) => {
      return firebase.database().ref(`/users/${users}`)
          .on('value', snapshot => {
              user_list_temp.push(snapshot.val());
              console.log(snapshot.val());
            })
        }
  );

Promise.all(phone_list_promise_1).then( () => console.log(user_list_temp) )

Я изменил код на этот, но все равно получаю неправильный вывод

Promise.all(arrWithKeys.map(async (users,i) => {
      const eventRef = db.ref(`users/${users}`);
      await eventRef.on('value', snapshot => {
        const value = snapshot.val();
        console.log(value);
        phone_user_list[0][users].name = value.name;
        phone_user_list[0][users].photo = value.photo;
      })
      console.log(phone_user_list[0]); 
      user_list_temp.push(phone_user_list[0]);
    }

  ));
    console.log(user_list_temp); //empty  array
}

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Можно использовать async/await с огненной базой

Так я обычно делаю Promise.all

const db = firebase.database();
let user_list_temp = await Promise.all(arrWithKeys.map(async (users,i) => {
    const eventRef = db.ref(`users/${users}`);
    const snapshot = await eventref.once('value');
    const value = snapshot.value();
    return value;
  })
);

Эта статья дает довольно хорошуюобъяснение использования Promise.all с async/await https://www.taniarascia.com/promise-all-with-async-await/

Вот как я бы реорганизовал ваш новый фрагмент кода, чтобы вы не смешивали promises и async/await

let user_list_temp = await Promise.all(arrWithKeys.map(async (users,i) => {
  const eventRef = db.ref(`users/${users}`);
  const snapshot=  await eventRef.once('value');
  const value = snapshot.val();
  console.log(value);
  phone_user_list[0][users].name = value.name;    // should this be hardcoded as 0?
  phone_user_list[0][users].photo = value.photo;  // should this be hardcoded as 0?
  console.log(phone_user_list[0]); 
  return phone_user_list[0];        // should this be hardcoded as 0?
  })
);
console.log(user_list_temp); 

Вот простой пример, который использует fetch вместо firebase:

async componentDidMount () {
  let urls = [
    'https://jsonplaceholder.typicode.com/todos/1',
    'https://jsonplaceholder.typicode.com/todos/2',
    'https://jsonplaceholder.typicode.com/todos/3',
    'https://jsonplaceholder.typicode.com/todos/4'
  ];
  let results = await Promise.all(urls.map(async url => {
    const response = await fetch(url);
    const json = await response.json();
    return json;
  }));
  alert(JSON.stringify(results))
}
0 голосов
/ 05 февраля 2019

Если я правильно понимаю ваш вопрос, вы можете подумать о пересмотре кода для использования обычного цикла for..of с вложенным обещанием для пользователя, которое разрешается, когда снимок / значение для этого пользователя доступно, как показано:

const user_list_temp = [];

/*
Use regular for..of loop to iterate values
*/
for(const user of arrWithKeys) {

    /*
    Use await on a new promise object for this user that
    resolves with snapshot value when value recieved for
    user
    */
    const user_list_item = await (new Promise((resolve) => {

        firebase.database()
        .ref(`/users/${users}`)
        .on('value', snapshot => {

            /*
            When value recieved, resolve the promise for
            this user with val()
            */    
            resolve(snapshot.val());
        });
    }));

    /*
    Add value for this user to the resulting user_list_item
    */
    user_list_temp.push(user_list_item);
}

console.log(user_list_temp);

В этом коде предполагается, что включающая функция определена как асинхронный метод с ключевым словом async, так как ключевое слово await используется в цикле for..of.Надеюсь, это поможет!

...