如何等待异步查询在for循环中完成?

时间:2020-01-24 09:29:55

标签: javascript node.js firebase google-cloud-functions

我想获取异步函数的结果-根据结果,我想执行另一个函数或继续for循环。这是我的云端功能:

return query.get().then(geoSnapshot => {
        // If GeoquerySnapshot returns 0 docs, createDoc()
        let docs = geoSnapshot.docs;
        if (docs.length === 0) return createDoc(data);
        for(let [index, doc] of docs.entries()){
            // If age preferences are valid, joinDoc
            let currentDoc = docs[index].data();
            if (validAge(currentDoc, data)){
                let matchedBefore = await(matchedBefore(currentDoc, data))
                if (!matchedBefore){
                    return joinDoc(docs[index], data);
                } else if (index === (docs.length - 1)) {
                    return createDoc(data);
                }
            }
            return
        }
    }).catch( error => {
        console.log("error query: " + error);
        return { error: error };
    })

async function matchedBefore(currentDoc, data){
    return db.collection('users').doc(data.uid).get().then( doc => {
        if ( !doc.exists ) return false;
        // If user1 in matchedUsers
        let matchedUsers = doc.get('matchedUsers');
        if (matchedUsers === undefined) return true
        let matchedBefore = matchedUsers.includes(currentDoc.user1);
        console.log('matchedBefore: ' + matchedBefore);
        if (matchedBefore) { 
            return false 
        } else {
            return true
        }
    })
}

我在let matchedBefore = await(matchedBefore(currentDoc, data))上遇到以下错误:

Each then() should return a value or throw

如何确保函数matchedBefore()在for循环继续之前完成?

1 个答案:

答案 0 :(得分:1)

我认为您对async-await的实现过于困惑。正确的方法是:

return query.get().then(async geoSnapshot => {
  // If GeoquerySnapshot returns 0 docs, createDoc()
  let docs = geoSnapshot.docs;
  if (docs.length === 0) return createDoc(data);
  /* eslint-disable no-await-in-loop */
  for(let [index, doc] of docs.entries()) {
    // If age preferences are valid, joinDoc
    let currentDoc = docs[index].data();

    if (validAge(currentDoc, data)){
      let matchedBefore = await(matchedBefore(currentDoc, data))
      if (!matchedBefore){
          return joinDoc(docs[index], data);
      } else if (index === (docs.length - 1)) {
          return createDoc(data);
      }
    }
    return
  }
  /* eslint-enable no-await-in-loop */
}).catch( error => {
    console.log("error query: " + error);
    return { error: error };
})

async function matchedBefore(currentDoc, data){
  let doc = await db.collection('users').doc(data.uid).get()
  
  if ( !doc.exists ) return false;

  // If user1 in matchedUsers
  let matchedUsers = doc.get('matchedUsers');
  if (matchedUsers === undefined) return true

  let matchedBefore = matchedUsers.includes(currentDoc.user1);
  console.log('matchedBefore: ' + matchedBefore);

  return !matchedBefore
}