此question的扩展,@ 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.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
,它将无效,state.videos
将不返回任何内容。
检查此article,特别是此声明
好吧,forEach()方法实际上并没有返回任何内容(未定义)。它只是在数组中的每个元素上调用一个提供的函数。允许此回调改变调用数组。
因此每个理论上也应该有效,但为什么不是这样呢?例如,forEach
应该像下面那样能够改变调用数组
let items = [
{id: '123', title: 'John'},
{id: '123', title:'sammy'}
]
items.forEach(x=> {
x['statistics'] = { propA: 'A', propB: 'B'};
})
console.log(items);
答案 0 :(得分:2)
您需要map
,因为Promise.all
需要数组的参数,通常将数组中的所有或部分元素作为Promise
s。如您所见,forEach
不会返回数组。事实上,一旦达到那个点就不会运行,会抛出错误:
Promise.all(undefined).then(() => console.log('ok'))
(index):30 Uncaught(in promise)TypeError:无法读取未定义的属性'Symbol(Symbol.iterator)' 在Function.all() 在window.onload((index):30)
您可能会遗漏async
函数自动返回Promises
,一旦到达其(可视)块结束就会解析。将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
});
}))
您必须return
创建的Promise,以便Promise.all
知道它需要等待数组中的所有Promise
首先解析 - 这有点掩盖了{{ 1}}原始代码的功能。