Как я могу перекодировать эту функцию, чтобы на самом деле ждать результатов в - PullRequest
1 голос
/ 27 апреля 2020

Итак, в основном я знаю, где проблема с моим кодом:

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
}

Я подумал, что проблема заключается в продолжении l oop, несмотря на то, что результат от другой функции asyn c не разрешен.

Мой вопрос: есть ли у кого-нибудь идея, как перекодировать эти циклы, чтобы вся функция фактически возвращала результат, а не пустые объекты? Любые другие комментарии, советы и рекомендации по улучшению этого кода ценится тоже.

1 Ответ

1 голос
/ 27 апреля 2020

Ваш await внутри forEach означает, что Обещание внутри не связано с чем-то снаружи. Вместо этого используйте .map, чтобы у вас были все результаты в виде массива Promises, а затем вызовите Promise.all для этого массива.

Вам также следует избегать явного * anti-pattern конструкции Promise : 1008 *:

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);
}

Не забудьте использовать const, а не let, когда вы не собираетесь переназначать переменную, и .map - это подходящий метод, который нужно использовать, когда вы хотите построить массив с помощью трансформируя все элементы другого.

...