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

