检测到包含http请求的forEach循环的末尾?

时间:2018-12-11 12:03:50

标签: javascript reactjs axios

我具有此功能,并且在forEach循环内迭代槽项目...我要实现的是渲染一些微调器(加载器),直到完成所有http请求,直到{ {1}}循环完成。

我现在尝试的方式是,第一个forEach和第一个console.log会立即触发,然后它会记录第二个console.log,其次数与items数组中的项目的次数相同。

在完成所有loading: false请求之后,forEach迭代完成后如何将状态更新为http

someHandler = () => {
    // this.setState({ loading: false })
       console.log( "Not loading" )
    this.props.items.forEach(item => {
      axios
        .get(`.../${item}/`)
        .then(res => {
          this.setState(prevState => ({
            item: [
              ...prevState.item,
              {
                name: res.data.name,
                img: res.data.img
              }
            ]
          }));
          this.props.newItem(this.state.item);
          // this.setState({ loading: true })
             console.log( "Loading" )
        })
        .catch(err => {
          console.log(err);
          // this.setState({ loading: false })
             console.log( "Not loading" )
        });
    });
    // this.setState({ loading: false })
       console.log( "Not loading" )
  };

2 个答案:

答案 0 :(得分:1)

您可以将async/awaitfor...of一起使用

您可以采用这种方法假定顺序执行。

someHandler = async () => {
  console.log('Not loading'); // will execute before loop
  this.setState({ loading: true }); // start loading

  for (let item of this.props.items) {
    const res = await axios.get(`.../${item}/`);
    // ... do your logic with response
    console.log('Loading');
  }

  console.log('Not loading'); // will execute after loop
  this.setState({ loading: false }); // end loading
};

答案 1 :(得分:1)

如果您无法在环境中使用async / await,并且想等到许多诺言得到解决,那么Promise.all是您的朋友。我可能错过了一些东西,但总而言之,您可以这样重写函数:

const requests = this.props.items.map(item => (
  axios.get(`...${item}`).then(res => {
    const newItem = { name: res.data.name, img: res.data.img }
    this.props.newItem(newItem)
    return newItem
  })
))

Promise.all(requests).then(responses => {
  this.setState({ item: responses })
})

这将创建一个名为requests的新承诺数组,当它们全部完成后,使用setState来设置所有响应。