fabian
fabian

Reputation: 5463

How to wait for Async/Await with nested foreach loop to be completed

how can I wait for getVideoCountForAuthor() to be completed with all async queries?

router.get('/', function (req, res, next) {

    console.log("START");

    (async () => {
        let uniqueAuthors = await getInfluencersForHashTags("winter", {  sessionList: [TTSessions]});
        uniqueAuthors = await getVideoCountForAuthor(uniqueAuthors);
    })()
        .then(() => {
            console.log("EVERYTHING DONE");
        })  ;


});

async function getVideoCountForAuthor(authors) {

    return _.each(authors, async function (author, i, authors) {

        let feed = await TikTokScraper.user(author.username, {number: 10, sessionList: [TTSessions]});

        let authorMeta = author.authorMeta;

        let videocounts = _.map(feed.collector, function (post) {
            return post.playCount;
        });

        console.log("set videocount");

    });
}

LOG:

START
EVERYTHING DONE
set videocount
set videocount
set videocount
set videocount

Upvotes: 0

Views: 1072

Answers (2)

jtwalters
jtwalters

Reputation: 1134

If you want to use lodash you can use map instead of each because map will return an array of answers (In your case empty Promises) so to change that scenario to the same scenario of each you can do this:

async function getVideoCountForAuthor(authors) {

    return _.map(authors, async function (author, i, authors) {

        let feed = await TikTokScraper.user(author.username, {number: 10, sessionList: [TTSessions]});

        let authorMeta = author.authorMeta;

        let videocounts = _.map(feed.collector, function (post) {
            return post.playCount;
        });

        console.log("set videocount");
        return author;
    });
}

Now, the answer will be an array of promises, so you can make a Promise.all in getVideoCountForAuthor or in the parent function.

The first case will be:


async function getVideoCountForAuthor(authors) {

    return await Promise.all(_.map(authors, async function (author, i, authors) {

        let feed = await TikTokScraper.user(author.username, {number: 10, sessionList: [TTSessions]});

        let authorMeta = author.authorMeta;

        let videocounts = _.map(feed.collector, function (post) {
            return post.playCount;
        });

        console.log("set videocount");
        return author;
    }));
}

Your output will be:

START
set videocount
set videocount
set videocount
set videocount
EVERYTHING DONE

Upvotes: 1

fabian
fabian

Reputation: 5463

Ohh wow. It works with a for loop. Is that the best option?

async function getVideoCountForAuthor(authors) {

    for (const author of authors) {

        let feed = await TikTokScraper.user(author.username, {number: 10, sessionList: [TTSessions]});

        let authorMeta = author.authorMeta;

        let videocounts = _.map(feed.collector, function (post) {
            return post.playCount;
        });

        //let newAuthor = author;
        // uniqueAuthors[i].medianVideoCounts = median(videocounts);
        console.log("set videocount");

    };
}

Upvotes: 1

Related Questions