You need to enable JavaScript to run this app. JS类使用fetch的Request请求Edamam API时dataJson返回undefined问题
优惠活动
大模型
产品
解决方案
定价
更多

JS类使用fetch的Request请求Edamam API时dataJson返回undefined问题

问题核心根源

你碰到的this.dataJson是undefined,既不是类写得有问题,也不是.then里的赋值逻辑错了,本质是JS异步执行的时序错位:

  • fetch是非阻塞的异步API,调用getJson()发出去网络请求后,代码根本不会停下来等服务器回数据,会直接顺着往下跑
  • 你紧接着写的pa.getData(),在网络请求还在传输的过程中就已经执行完了。这时候.then里给this.dataJson赋值的回调根本还没触发,读到的自然是构造函数里留的初始空值(也就是undefined)
  • 等个几百毫秒网络请求回来了,赋值逻辑才会跑,但这时候getData()早就把日志打完了,你自然看不到赋值后的数据。
直接能用的修复方案

第一步:把fetch的Promise从getJson方法返回出去

现在你的getJson()是没有返回值的,外面的代码根本不知道请求什么时候能跑完,自然没法控制执行顺序。只要把整个fetch的请求链return出去就行:

getJson(){
  // 关键改动:把整个fetch的Promise返回给外层调用者
  return fetch(new Request(this.url, { method: 'GET' }))
    .then(response => response.json())
    .then(data => {
      // 原来的赋值逻辑本身没毛病
      this.dataJson = data;
      console.log('接口拉到的原始食谱数据:', data)
      // 把数据透传出去,方便后续链式调用
      return data
    })
    .catch(e => {
      console.error('请求出问题了:', e)
      // 别把错误吞了,往外抛让外层能捕获到
      throw e
    })
}

第二步:等请求彻底完成再读dataJson

现在getJson()返回了Promise,就可以等它跑完,再调用读数据的方法,就不会拿到undefined了。两种写法挑顺手的用:

  • 链式写法,改动最小:
const pa = new Recipe('https://api.edamam.com/search?...');
// 等请求全跑完了,再执行getData
pa.getJson().then(() => {
  pa.getData(); // 这时候this.dataJson已经是接口返回的真实数据了
});
  • async/await写法,后续扩展更顺:
// 用异步函数包下应用初始化的逻辑
async function initRecipeApp(){
  const pa = new Recipe('https://api.edamam.com/search?...');
  // 阻塞等请求完成,再往下走
  await pa.getJson();
  pa.getData();
}
initRecipeApp()
新手容易踩的几个小坑
  • 你现在抽Recipe类管请求逻辑的思路完全是对的,要发3次不同的食谱请求,只要给每个请求urlnew一个对应的Recipe实例就行,不用改类的现有结构
  • 别图省事在构造函数里直接发fetch请求,不然new实例的时候就自动触发请求,既没法灵活控制什么时候发请求,也容易出了错捕不到
  • 构造函数里预先留this.dataJson属性的写法没问题,但要记着它是异步赋值的,不能像读普通同步变量那样,实例化完立马就读

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.11 05:24:05