开发者问题收集

如何在 Firestore Firebase 中使用承诺

2021-03-28
184

我尝试使用键数组和 map 函数从 Firestore 读取一些数据,然后,当所有数据从 Firestore 返回时,对结果数据集运行一个函数。此代码有效,但顺序不正确;我正在努力使 doSomethingUsefulWithData() 延迟到 arrayOfDataFromFirestore 完成。

我尝试过 await,但收到一条错误消息,提示“未捕获的语法错误:await 仅在异步函数和异步生成器中有效”。我认为下面显示的 await 异步函数中,但显然不是。

如果我运行此处显示的版本,doSomethingUsefulWithData() 会在 getData() 之前运行,尽管它后面跟着一个 .then。

var arrayOfFirestoreKeys = [key0, key1, key3];
    
    function doSomethingUsefulWithData(){
        //Do something useful with the data here
    };
    
    function dataGet(){
        var arrayOfDataFromFirestore = [];
        arrayOfDataFromFirestore = Promise.all(arrayOfFirestoreKeys.map(async (dataGet, index) => {
            var docRef = db.collection('dataInFirestore').doc(arrayOfFirestoreKeys[index]).get().then((doc) => {
                if (doc.exists) {
                    console.log("Document data from async:", doc.data());
                    //doSomethingUsefulWithData here works but runs n times for n items in arrayOfFirestoreKeys
                };  
                //Trying await doSomethingUsefulWithData here produces warning 'await must be in async function or function generator'
            });
            //Trying await doSomethingUsefulWithData here produces warning 'await must be in async function or function generator'
        }))
        return(arrayOfDataFromFirestore);
    };
    
    arrayOfDataFromFirestore = dataGet().then(doSomethingUsefulWithData(arrayOfDataFromFirestore));
    //With this version of the code,
    //doSomethingUsefulWithData runs first and produces a complaint that arrayOfDataFromFirestore is undefined.
    //Then the contents of arrayOfDataFromFirestore follow into console.log
1个回答

如果我正确理解了您的问题,以下内容应该可以解决问题:

  var arrayOfFirestoreKeys = [key0, key1, key3];

  function doSomethingUsefulWithData(arrayOfSnapshots) {
    // arrayOfSnapshots is an Array of DocumentSnapshot
    arrayOfSnapshots.forEach(docSnap => {
        if (docSnap.exists) {
            // Do something
        }
    });
  }

  function dataGet() {
    const arrayOfDataFromFirestore = arrayOfFirestoreKeys.map((k) =>
      db.collection('dataInFirestore').doc(k).get()
    );
    return Promise.all(arrayOfDataFromFirestore);
  }

  dataGet().then(array => {
    doSomethingUsefulWithData(Array);
  });
  
Renaud Tarnec
2021-03-28