简体   繁体   中英

Call an async function in foreach loop and return array once loop is done

I'm trying to request data from an API in a foreach loop and push that data to an array and then return that array at the end. Here is my code:

db
            .collection('posts')
            .orderBy('createdAt', 'desc')
            .limit(10)
            .get()
            .then((data) => {
                let posts = [];
                data.forEach((doc) => {
                    db
                        .doc(`/users/${doc.data().userHandle}`)
                        .get()
                        .then((userDoc) => {
                            posts.push({
                                postId: doc.data().id,
                                userHandle: doc.data().userHandle,
                                userImageUrl: userDoc.data().imageUrl,
                                imageUrl: doc.data().imageUrl,
                            });
                        })
                })
                return res.json(posts);
            })
            .catch((err) => {
                console.error(err);
                res.status(500).json({ error: err.code});
            });

From this, the posts array return en empty array or object, even when i replace return res.json(posts) with

.then(() => {
return res.json(posts);
})

Any help is awesome!!!

The array is empty because by the time the response is sent, promises with posts are still pending resolution.

In order to fix this issue, you can collect all the promises in an array using .map() , wait for them to resolve with help of Promise.all() and send the response after that:

db
  .collection('posts')
  .orderBy('createdAt', 'desc')
  .limit(10)
  .get()
  .then((data) => {
    const promises = data.map((doc) => {
      return db
        .doc(`/users/${doc.data().userHandle}`)
        .get()
        .then((userDoc) => {
          return {
            postId: doc.data().id,
            userHandle: doc.data().userHandle,
            userImageUrl: userDoc.data().imageUrl,
            imageUrl: doc.data().imageUrl,
          };
        })
    });
    Promise.all(promises).then(posts => {
      res.json(posts);
    })
  })
  .catch((err) => {
    console.error(err);
    res.status(500).json({ error: err.code});
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM