You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

fetch获取JSON赋值变量报不可迭代错误的解决方法

问题根因

这个报错和赋值操作本身无关,核心是fetch是异步非阻塞API:你发起fetch请求后,JS引擎不会等待接口返回,会直接执行后续用到advi变量的逻辑。此时接口还没响应,advi还是初始的undefined值,只要你对undefined做解构、循环遍历这类依赖迭代器的操作,就会抛出undefined is not iterable的错误。
你把回调换成.then(console.log)能正常输出,是因为console.log被放在Promise的回调链里,只有接口成功返回、JSON解析完成后才会执行,自然能拿到正确数据。

可行实现方案

不要用提前声明外部变量、等异步赋值后再使用的写法,这种写法时序不可控,非常容易出bug,推荐以下两种标准写法:

方案1:Promise 链式调用

把所有依赖接口返回值的业务逻辑,直接放到Promise的then回调链中执行,同时记得加错误捕获:

fetch("https://api.adviceslip.com/advice")
  .then(res => {
    if (!res.ok) throw new Error("接口请求异常")
    return res.json()
  })
  .then(advData => {
    // 所有用到advice数据的逻辑全部写在这里
    const adviceText = advData.slip.advice
    // 示例:将内容渲染到页面
    document.getElementById("advice-content").textContent = adviceText
  })
  .catch(err => console.error("请求失败:", err))

方案2:async/await 语法糖(更易维护)

如果觉得链式回调嵌套不好维护,可以用async/await写异步逻辑,写法和同步代码逻辑一致,注意必须包裹在async函数内:

async function loadAdvice() {
  try {
    const res = await fetch("https://api.adviceslip.com/advice")
    if (!res.ok) throw new Error("接口请求异常")
    const advData = await res.json()
    
    // 此处可以直接使用返回的advData写业务逻辑
    const adviceText = advData.slip.advice
    document.getElementById("advice-content").textContent = adviceText
    
    // 如果其他逻辑需要用到这份数据,直接return即可
    return advData
  } catch (err) {
    console.error("请求失败:", err)
  }
}

// 执行函数
loadAdvice()
注意事项
  • 绝对不要在fetch异步回调的外部,直接读取你提前声明的advi变量:在fetch语句后立刻操作advi,100%会拿到undefined,因为此时接口请求还没完成。
  • 如果确实需要把数据存在全局/外层作用域复用,必须加加载状态判断,确认数据已经赋值完成后再执行对应逻辑,这种写法维护成本高,非必要不推荐。

内容的提问来源于stack exchange,提问作者supasiblings

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 01:42:27