我具有此功能,并且在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" )
};
答案 0 :(得分:1)
您可以将async/await
与for...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
来设置所有响应。