简体   繁体   中英

Return a value from loop in JavaScript?

I was creating a function to delete indexes that do not match the required amount of "levels" in my database, then return that array.

The problem is when I do cleanWinners(winners, guild).then(res => console.log(res)) I receive undefined. I assume the code is not waiting for this function to end before returning the array? How can I fix that?

When I use this code:

async function cleanWinners(winners, guild) {
    let returnedArray;

    for (const winner of winners) {
        XP.findOne({serverID: guild.id, userID: winner}, (err, xpTable) => {
            if (err) throw err;
            if (!xpTable) {
                const newXP = new XP({
                    totalXP: 0,
                    xp: 0,
                    level: 0,
                    date: 0,
                    serverID: guild.id,
                    userID: winner
                });
                newXP.save().catch(console.log);
                xpTable = newXP;
            }
            // If they have less than the set amount, get a new winner.
            if (xpTable.level < 1) {
                const index = winners.indexOf(winner);
                delete winners[index];
            }
            console.log('Removed less than level 1', winners);
            let newWinner = getWinners(winners, 1);
            winners = winners.concat(newWinner);
            console.log('New Winner array:', winners);
            returnedArray = winners;
        });
    }
    return returnedArray;
}
// 503418431861948418 should be removed, the other should stay.
// This code returns undefined before the loop even starts. I want this to run AFTER the loop has completed, no matter the amount of entries the array has.
cleanWinners(['209797091457761280','503418431861948418'], message.guild.id)
.then(res => console.log(res));

This is the result I get in my console:

undefined
Less than 1 level removed [ '209797091457761280', '503418431861948418' ]
New winners array [ '209797091457761280', '503418431861948418' ]
Less than 1 level removed [ '209797091457761280', <1 empty item> ]
New winners array [ '209797091457761280', <1 empty item> ]```

The problem is XP.findOne function is async and you passed a callback to it. So it'll not wait for everything to finish before return returnedArray . You should use await on findOne await XP.findOne(... then your code will work in the way you're expecting it to.

Here's a great mozilla link for async await if you want to check out https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await

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