循环数组时如何确保更新?Axios请求中TypeError报错排查
Cannot read properties of undefined (reading 'episodes')错误 我需要连续发起两次Axios GET请求:第一次请求完成后,遍历响应数据简化每个返回对象,只保留所需字段(即第一个循环中的data[i]);之后通过第一次请求得到的key值(query2)发起第二次GET请求,获取单个对象的子数据——这部分数据无法通过单次请求获取。
接着我用第二个循环,把第二次响应中的所有子对象逐个附加到父对象(data[i])中。但第二个循环经常(并非每次都会)抛出以下错误:
TypeError: Cannot read properties of undefined (reading 'episodes')
at newAdditionCheck (...bot\plexTV.js:89:26)
at runMicrotasks ()
at processTicksAndRejections (node:internal/process/task_queues:96:5)
错误出现在data[i].episodes.push(data2[j])这一行。我在循环中打印过各个对象,它们都正常存在,推测是部分循环的执行顺序出了问题,希望得到修复建议或方案。
原始代码
let baseURL1 = `http://${plexKeys.hostname}:${plexKeys.port}`; let baseURL2 = `/?X-Plex-Token=${plexKeys.token}`; const response = await axios({ method: "GET", url: `${baseURL1}${query}${baseURL2}`, }); let data = response.data.MediaContainer.Metadata; for (i = 0; i < data.length; i++) { data[i] = { name: data[i].parentTitle, key: data[i].queryToken, episodes: [], }; query2 = data[i].key; const response2 = await axios({ method: "GET", url: `${baseURL1}${query2}${baseURL2}`, }); let data2 = response2.data.MediaContainer.Metadata; for (let j in data2) { data2[j] = { series: data2[j].grandparentTitle, season: data2[j].parentTitle, }; data[i].episodes.push(data2[j]); } continue; }
问题根源与修复方案
修复全局变量导致的作用域问题
第一个循环中的i没有用let/const声明,属于全局变量。当异步请求的回调执行时,i可能已经被循环更新到超出data数组长度的数值,导致data[i]变为undefined,访问episodes自然报错。
调整代码:for (let i = 0; i < data.length; i++) { // 原有逻辑保持不变 }避免原数组被意外修改
直接操作接口返回的原数组可能存在风险,建议先浅拷贝一份,防止其他代码意外修改数组内容:let data = [...response.data.MediaContainer.Metadata];增加数据空值校验
考虑接口返回数据异常的情况(比如response2.data.MediaContainer.Metadata可能为undefined),提前做空值校验:let data2 = response2.data?.MediaContainer?.Metadata || [];优化数组遍历方式
for...in遍历数组可能会读取到原型链上的额外属性,建议改用更安全的for...of或普通for循环:for (const item of data2) { const episode = { series: item.grandparentTitle, season: item.parentTitle, }; data[i].episodes.push(episode); }
内容的提问来源于stack exchange,提问作者Peyton Sonnefeld

