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

React中每秒发起请求至res.readyToShow为true的实现及报错解决

问题描述

需求:在React中每秒发起一次fetch请求,直到返回结果res.readyToShow === true时停止请求,无法使用Socket或Webhooks。
执行代码后出现报错:

TypeError: Cannot read properties of undefined (reading 'test')

相关代码:

test = (ossUrn, md5Checksum) => setTimeout(() => {
    fetch(
      `google/isReadyToShow`,{
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        urn: ossUrn,
        md5Checksum: md5Checksum,
      }),
    })
    .then((response) => {
      response.json().then((res) => {
          console.log('response ', res);
          return (res.readyToShow) ? 0 : this.test(ossUrn, md5Checksum);
        });
    })
    .catch((err) => {
      console.log('err ', err);
    });
}, 2500);
return fetch(
  `google/translation`,
  {
    headers: {
      'X-ACCESS-TOKEN-APP' : accessTokenApp,
      'X-DRIVE-ID': e.itemData.id,
      'X-FILE-NAME': e.itemData.name,
      'X-FILE-TYPE': e.itemData.mimeType,
      'X-FILE-MD5': e.itemData.md5Checksum,
    },
  }
)
.then((response) => {
    console.log("google item of id clicked " + e.itemData.id);
    response.json().then((res) => {
      console.log('response ', res);
      md5Checksum = e.itemData.md5Checksum;
      ossUrn =  res.urn;
      console.log('URN ', ossUrn)
      console.log('URL', res);
      console.log('MD5', md5Checksum);
      // 执行检查文件是否准备好展示的函数
      this.test(ossUrn, md5Checksum);
    })         
    .catch((err) => {
      console.log(err);
    });
}).catch(() => { throw new Error('Data Loading Error'); });
问题分析与解决

报错原因

报错核心是this指向异常:

  1. 在嵌套的response.json().then()回调中,this没有绑定到React组件实例,导致调用this.test时this为undefined。
  2. 原代码使用嵌套then的写法,不仅可读性差,还容易导致上下文丢失。

修正方案

1. 确保this指向正确

通过async/await替代嵌套then,既能提升代码可读性,又能保留组件上下文;同时新增定时器管理逻辑,避免内存泄漏。

修正后的完整代码

// 定义定时器变量,用于后续清理
checkTimer = null;

test = async (ossUrn, md5Checksum) => {
  try {
    const response = await fetch(`google/isReadyToShow`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        urn: ossUrn,
        md5Checksum: md5Checksum,
      }),
    });

    if (!response.ok) {
      throw new Error(`请求失败:${response.status}`);
    }

    const res = await response.json();
    console.log('response ', res);

    if (!res.readyToShow) {
      // 未就绪则继续定时请求
      this.checkTimer = setTimeout(() => this.test(ossUrn, md5Checksum), 2500);
    } else {
      // 就绪后清理定时器,执行后续逻辑
      clearTimeout(this.checkTimer);
      console.log('文件已准备好展示');
      // 这里可以添加就绪后的业务处理代码
    }
  } catch (err) {
    console.log('err ', err);
    // 请求失败时清理定时器,避免无限重试
    clearTimeout(this.checkTimer);
  }
};
return fetch(
  `google/translation`,
  {
    headers: {
      'X-ACCESS-TOKEN-APP' : accessTokenApp,
      'X-DRIVE-ID': e.itemData.id,
      'X-FILE-NAME': e.itemData.name,
      'X-FILE-TYPE': e.itemData.mimeType,
      'X-FILE-MD5': e.itemData.md5Checksum,
    },
  }
)
.then(async (response) => {
  console.log("google item of id clicked " + e.itemData.id);
  const res = await response.json();
  console.log('response ', res);
  const md5Checksum = e.itemData.md5Checksum;
  const ossUrn = res.urn;
  console.log('URN ', ossUrn)
  console.log('URL', res);
  console.log('MD5', md5Checksum);
  // 执行检查函数
  this.test(ossUrn, md5Checksum);
})
.catch((err) => {
  console.log(err);
  throw new Error('Data Loading Error');
});

关键改进点

  • 用async/await替代嵌套then,避免上下文丢失,代码更易读;
  • 新增checkTimer变量管理定时器,在请求就绪或失败时清理,防止内存泄漏;
  • 添加response.ok检查,处理HTTP请求失败的场景;
  • 确保this.test调用时上下文正确,箭头函数和async/await会保留组件实例的this指向。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 08:21:57