async / await:等待循环结束,然后返回函数结果

时间:2020-06-08 09:15:13

标签: javascript async-await

我有下一个功能:

    async getPopular() {
      return await tryCatchWithApolloErrorAsync(async () => {
        const popular = await adminService
          .firestore()
          .collection(api.counters)
          .doc('companies-by-categories')
          .collection('categories')
          .get()

        let data: Popular[] = []

        popular.docs.map(element => {
          getCount(element.ref).then(count => {
            if (count > 0) {
              data.push({
                id: parseInt(element.id),
                amount: count
              })
            }
          })
        })

        return data
      })
    },

但是它总是返回一个空数组,即使在map循环中我有一些数据。在返回空的popular.docs.map数组之前,如何使其等待data完成?

1 个答案:

答案 0 :(得分:2)

如果不使用返回值,请不要使用map。让您的代码创建一个数组,您将立即将其丢弃是没有意义的。

如果您希望调用以并行运行 的计数,则可以将mapPromise.all一起使用诺言:

async getPopular() {
  return await tryCatchWithApolloErrorAsync(async () => {
    const popular = await adminService
      .firestore()
      .collection(api.counters)
      .doc('companies-by-categories')
      .collection('categories')
      .get()

    let data: Popular[] = []

    await Promise.all(popular.docs.map(async element => { // `async` function
      const count = await getCount(element.ref)           // returns a promise
      if (count > 0) {
        data.push({
          id: parseInt(element.id),
          amount: count
        })
      }
    }))

    return data
  })
},

另一种方法是使用filter

async getPopular() {
  return await tryCatchWithApolloErrorAsync(async () => {
    const popular = await adminService
      .firestore()
      .collection(api.counters)
      .doc('companies-by-categories')
      .collection('categories')
      .get()

    let data: Popular[] = await Promise.all(popular.docs.map(async element => ({
      id: parseInt(element.id),
      count: await getCount(element.ref)
    })));

    return data.filter(({count}) => count > 0)
  })
},

如果希望它们按顺序运行,请使用for-of循环:

async getPopular() {
  return await tryCatchWithApolloErrorAsync(async () => {
    const popular = await adminService
      .firestore()
      .collection(api.counters)
      .doc('companies-by-categories')
      .collection('categories')
      .get()

    let data: Popular[] = []

    for (const element of popular.docs) {
      const count = await getCount(element.ref)
      if (count > 0) {
        data.push({
          id: parseInt(element.id),
          amount: count
        })
      }
    }

    return data
  })
},