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
相关产品推荐
相关产品推荐

