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

JS fetch连续两次调用response.json()为何后续.then不执行

Fetch请求中连续调用response.json()导致后续.then不执行的原因

核心原理

Response对象的请求体(body)是只读的单向ReadableStream(可读流),流的读取操作是一次性的:一旦被某个读取方法消费,就会被锁定,无法再次读取。
response.json()、response.text()、response.blob()、response.formData()这类方法的本质,都是消费body流、将原始二进制数据解析为对应格式的内容,返回一个Promise。同一个Response对象上,这类方法只能成功调用一次。

代码问题分析

  • 异常代码的问题:在第一个.then里连续调用了两次response.json()
    • 第一次执行console.log(response.json())时,已经触发了流的读取,body流被第一次调用消费、锁定
    • 第二次执行return response.json()时,流已经被读取完毕,方法会直接返回一个rejected状态的Promise,抛出「Body has already been read」类型的错误,Promise链直接进入异常分支,由于没有写.catch()捕获错误,所以看不到控制台报错,后续的.then自然不会执行
  • 正常运行的代码逻辑:只调用了一次response.json(),把返回的Promise存在变量resp中,后续打印、返回操作都是复用同一个Promise实例,没有重复消费body流,所以流程能正常走到第二个.then,拿到解析后的JSON数据。

正确写法参考

const fetchPromise = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json');
console.log(fetchPromise)
    
fetchPromise
.then( response => {
  const resp = response.json(); // 仅调用一次读取方法,拿到解析Promise
  console.log(resp);
  return resp;
})
.then( json => {
  console.log(json[0].name); // 正常输出: baked beans
})
.catch(err => {
  // 建议始终添加catch捕获请求、解析阶段的异常
  console.error('请求处理异常:', err);
});

注意:所有读取Response body的方法都遵循「只能调用一次」的规则,不要在同一个Response上重复调用这类读取方法,也不要同时调用多个不同的body读取方法(比如先调用json()再调用text()),否则都会触发流读取错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:33:21