Javascript forEach不工作,但map正在运行
@CertainPerformance的解决方案可以很好地解决这个问题Javascript forEach不工作,但map正在运行,javascript,arrays,Javascript,Arrays,@CertainPerformance的解决方案可以很好地解决这个问题 const query = qs.stringify({ ...API_QUERY_PARAMS, q: this.state.searchString }); const url = `https://www.googleapis.com/youtube/v3/search?${query}` const { data } = await axios.get(url); await Promise.all(data.i
const query = qs.stringify({ ...API_QUERY_PARAMS, q: this.state.searchString });
const url = `https://www.googleapis.com/youtube/v3/search?${query}`
const { data } = await axios.get(url);
await Promise.all(data.items.map(async (vid) => {
let id = vid.id.videoId; //Individual video ID
const individualQuery = qs.stringify({ ...INDIVIDUAL_API_QUERY_PARAMS, id });
const individualURL = `https://www.googleapis.com/youtube/v3/videos?${individualQuery}`;
const { data } = await axios.get(individualURL);
vid.statistics = data.items[0].statistics
}))
this.setState({ videos: data.items });
我想它可以用forEach
而不是map
。但是,如果我切换到forEach
它将什么也不做,并且状态。视频将什么也不返回
从这个,特别是这个陈述中检查
好的,forEach()方法实际上不返回任何内容(未定义)。它只是对数组中的每个元素调用提供的函数。允许此回调对调用数组进行变异
因此forEach理论上也应该起作用,但为什么不是这样呢?例如,forEach
的行为应该如下所示,它能够改变调用数组
let项目=[
{id:'123',标题:'John'},
{id:'123',标题:'sammy'}
]
items.forEach(x=>{
x['statistics']={propA:'A',propB:'B'};
})
控制台日志(项目)
您需要map
,因为Promise.all
需要数组的参数,通常数组中的所有或部分元素都是Promise
s。如您所见,forEach
不返回数组。事实上,一旦达到该点,它将根本不会运行,将抛出一个错误:
Promise.all(undefined).then(() => console.log('ok'))
(索引):30未捕获(承诺中)类型错误:无法读取未定义的属性“Symbol(Symbol.iterator)”
at Function.all()
在window.onload((索引):30)
您可能没有看到async
函数自动返回承诺
,一旦到达其(可视)块的末尾,这些承诺就会得到解决。将async
函数转换为标准函数会执行完全相同的操作,并显式返回Promise
,代码如下所示:
await Promise.all(data.items.map((vid) => {
const id = vid.id.videoId;
const individualQuery = qs.stringify({ ...INDIVIDUAL_API_QUERY_PARAMS, id });
const individualURL = `https://www.googleapis.com/youtube/v3/videos?${individualQuery}`;
return axios.get(individualURL)
.then(({ data }) => {
vid.statistics = data.items[0].statistics
});
}))
您必须返回所创建的承诺,以便承诺。all
知道它需要等待数组中的所有承诺首先解析-这在某种程度上被原始代码的异步函数所掩盖。因为您需要将承诺返回到承诺.all
。罗伯特:是的,我想我知道map是如何工作的,但在这种情况下,我可能真的不知道如何保证。所有的
都起作用,而不是在函数中使用
保证。所有的
都不变异,在执行其他操作之前,您将等待所有承诺得到解决,否则将使异步代码同步。只需setState
为您获取的每个视频setState(state=>({…state,videos:[…state.videos,data]}))
。