forEach不起作用,但地图是

时间:2018-06-13 08:50:02

标签: javascript arrays

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);

1 个答案:

答案 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}}原始代码的功能。