如何在double forEach中处理异步函数?

时间:2019-02-16 10:31:03

标签: reactjs react-native asynchronous

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

当我在控制台登录状态时,将获取数据,但是在渲染时,会出现延迟,该延迟有时会显示数据,有时却不会显示...我搜索了在forEach中使用异步的问题。卡住了,请帮助我...

2 个答案:

答案 0 :(得分:0)

我认为这是因为componentDidMount函数将不等待内部forEach完成,并且具有空数据的元素将被推送到newEvent(尽管您等待了foreach内的每个操作,但无法等待foreach循环整体)
因此,您可以执行以下两种方法之一

首先,使用map将另一个数组转换为promise数组,并使用Promise.all等待每个promise完成
注意:兑现每个承诺都会导致整个承诺被拒绝
因此它将如下所示:

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循环来迭代数组。

答案 1 :(得分:0)

您应该编写自己的forEach实现,以支持异步/等待。我为您写了一个小片段:

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

中执行该代码