Как обработать асинхронную функцию внутри double forEach? - PullRequest
0 голосов
/ 16 февраля 2019

У меня есть такой код внутри моего componentDidMount

arrayDate.forEach( (date) => {
    var tempData = []
    anotherArray.forEach(async(event) => {
      if(event.local_date == date){
        const groupNew = await this.getGroupDetailInfo(event.group.urlname)
        event.newGroup = groupNew
        tempData.push(event)
      }
    })
    let tempObj = {
      title: date, 
      data: tempData
    }
    newEvent.push(tempObj)
  })
getGroupDetailInfo = async(urlname) => {
    try {
      let response = await fetch(`https://api.meetup.com/${urlname}`);
      let responseJson = await response.json();
      return responseJson;
    } catch (error) {
      console.error(error);
    }
  }

Когда я console.log состояние, данные будут получены, но при рендеринге, есть задержка, которая иногда приводит к отображению данных, а иногданет ... У меня есть поиск, что есть проблема в использовании async в forEach .. Но я все еще застрял, пожалуйста, помогите мне ...

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

Вы должны написать свою собственную реализацию forEach, которая поддерживает async / await для этого.Я написал небольшой фрагмент для вас:

async function asyncForEach(array, callback) {
    try {
        for (let index = 0; index < array.length; index++) {
            await callback(array[index], index, array);
        }
    } catch (e) {
        console.error("Error in asyncForEach: ", e);
    }
}

Измените код, чтобы использовать его следующим образом:

await asyncForEach(arrayDate, async date => {
    var tempData = []
    await asyncForEach(anotherArray, async event => {
      if(event.local_date == date){
        const groupNew = await this.getGroupDetailInfo(event.group.urlname)
        event.newGroup = groupNew
        tempData.push(event)
      }
    })
    let tempObj = {
      title: date, 
      data: tempData
    }
    newEvent.push(tempObj)
})

Просто имейте в виду, что вы должны выполнить этот код внутриasync function

0 голосов
/ 16 февраля 2019

Я думаю, это потому, что функция componentDidMount не будет ждать завершения внутреннего forEach, а элементы с пустыми данными будут помещены в newEvent (хотя вы ожидали каждую операцию внутри foreach, нет способа ожидания цикла foreachв целом)
Таким образом, вы можете сделать один из двух способов

Сначала используйте map для преобразования другого массива в массив обещаний и используйте Promise.all, чтобы дождаться выполнения каждого обещания
Внимание: Добавление каждого из обещаний приведет к отклонению всего обещания
Так что это будет выглядеть так:

arrayDate.forEach(date => {
  Promise.all(
    anotherArray.map(
      event => (event.local_date === date ? this.getGroupDetailInfo(event.group.urlname) : Promise.resolve()),
    )
  ).then(groupsArray => groupsArray.filter(g => g.newGroup))
   .then(groupsArray => newEvent.push({ title: date, data: groupsArray }));
});

Во-вторых, мы можем сделать нашу функцию componentDidMount асинхронной и использовать нормальный цикл for дляитерация массивов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...