1

So basically i know where the problem with my code is

export async function hourlyUpdate(bot:Discord.Client){
    let result=new Promise<ActiveSubscriberList>(async (resolve,reject)=>{
        let fileData=await getDataFromFile()
        let resultList:ActiveSubscriberList={Server:[]}
        fileData.channels.forEach(async(element,index)=>{
            let tempArr=[]
            element.subscriber.forEach(element => {
                tempArr.push(element.userID)
            })
            let tempEntry={Channel:element.channelID,Subscriber:await actualFetch(bot,element.guildID,tempArr)}
            resultList.Server.push(tempEntry)
        })

        resolve(resultList)
    }).then(value=>{

    })
    return result

}
async function actualFetch(bot:Discord.Client,guildID:string,userArr:string[]){
    let result= new Promise<string[]>(async (resolve)=>{
        let activeSubs=[]
        let tempSubArray=await bot.guilds.cache.get(guildID).members.fetch({ user: userArr, withPresences: true })
        tempSubArray.forEach(element=>{
            activeSubs.push(element.user.id)
        })
        resolve(activeSubs)
    })
    return result
}

I figured the problem lies within the loop continuing despite the result from the other async function is not reolved.

My question is if anybody has an idea on how to recode those loops, so that the whole function actually returns the result rather than empty objects.Any other comments, tips and advice on how to make this code better is appreciated too.

DDaniel
  • 25
  • 3
  • You can't use `async` with `forEach` switch it to `for...of` loop. https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop – Ivan V. Apr 26 '20 at 22:28

1 Answers1

1

Your await inside the forEach means that the Promise inside isn't chained with anything outside. Instead, use .map so that you have all the results as an array of Promises, then call Promise.all on that array.

You should also avoid the explicit Promise construction antipattern:

export async function hourlyUpdate(bot: Discord.Client) {
  const fileData = await getDataFromFile();
  const Server = await Promise.all(fileData.channels.map(async (element) => {
    const tempArr = element.subscriber.map(element => element.userID);
    const Subscriber = await actualFetch(bot, element.guildID, tempArr);
    return { Channel: element.channelID, Subscriber };
  }));
  return { Server };
}
async function actualFetch(bot: Discord.Client, guildID: string, userArr: string[]) {
  const tempSubArray = await bot.guilds.cache.get(guildID).members.fetch({ user: userArr, withPresences: true });
  return tempSubArray.map(element => element.user.id);
}

Remember to use const, not let, when you aren't going to reassign a variable, and .map is the appropriate method to use when you want to construct an array by transforming all elements of another.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320