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

Express/Node+React中如何等待前一请求完成再执行下一请求

问题原因

现有代码存在两处时序问题,导致GET请求会在后端数据处理完成前就发起:

  • 前端调用postReq()时没有等待异步请求执行完成,POST发出后立刻触发了GET请求
  • 后端POST接口没有等待「调用iTunes API」「写入data.json文件」两个异步操作完成就返回了响应,前端收到POST响应时,后端大概率还没完成数据处理,此时GET请求拿到的要么是旧数据,要么会因为文件不存在/未写完报错
修复方案

需要同时修改前后端代码,保证「后端POST接口全流程处理完成才返回响应」「前端等POST响应确认成功后再发GET请求」。

后端(Express/Node)修改

核心是把POST接口改成等所有异步操作执行完成再返回响应,同时补上错误处理,避免服务崩溃。

// 引入依赖,注意Node 18以下版本需要手动安装node-fetch包
const fetch = require('node-fetch');
// 用promise版本的fs替代回调版本,更方便控制异步时序
const fs = require('fs/promises');

app.post('/', async (req, res) => {
  try {
    // 对请求参数做编码,避免特殊字符导致iTunes接口请求失败
    const searchKey = encodeURIComponent(req.body.search);
    const mediaType = encodeURIComponent(req.body.mediaType);
    // 等待iTunes接口返回结果
    const itunesRes = await fetch(`https://itunes.apple.com/search?term=${searchKey}&entity=${mediaType}&limit=8`);
    const data = await itunesRes.json();
    console.log(data);
    // 等待文件写入完成
    await fs.writeFile("data.json", JSON.stringify(data));
    // 所有操作完成后,再给前端返回成功响应
    res.json({ success: true });
  } catch (err) {
    // 捕获异常,返回错误信息,不要直接throw err打崩服务
    res.status(500).json({ success: false, msg: err.message });
  }
})

app.get('/api', async (req, res) => {
  try {
    const fileContent = await fs.readFile("data.json", "utf-8");
    res.json(JSON.parse(fileContent));
  } catch (err) {
    res.status(500).json({ success: false, msg: err.message });
  }
})

前端(React)修改

核心是等待POST请求确认处理成功后,再执行GET请求逻辑。

async function postReq() {
  const res = await fetch('http://localhost:3001/', {
    method: "POST",
    headers:{ "Content-Type": "application/json" },
    body: JSON.stringify(userData)
  })
  if (!res.ok) throw new Error('POST请求异常');
  return res.json();
}

// 函数改成async,方便用await控制时序
const fetchData = async (e) =>{
  e.preventDefault();
  try {
    // 等待POST请求全流程处理完成
    await postReq();
    // POST成功后再发起GET请求
    const response = await fetch('http://localhost:3001/api');
    if (!response.ok) throw new Error('GET请求异常');
    const data = await response.json();
    sessionStorage.setItem(`${mediaType}`, JSON.stringify(data))
  } catch (err) {
    console.error('请求失败:', err);
    // 可在此处添加用户侧错误提示,比如弹窗提示搜索失败
  }
}

可选优化:如果业务没有要求必须把iTunes返回的数据落地到本地json文件,可以直接在POST接口拿到iTunes数据后,直接把数据放在POST响应里返回给前端,省去一次GET请求和文件读写开销,逻辑更简洁,也不会出现时序问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:18:23