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

Express通过Axios向React返回数据失败:Promise pending问题排查

问题

我正在开发一款追踪厨师及其发布新食谱的应用:前端基于React实现,可输入厨师用户名并发送至Express后端;后端通过cheerio爬取美食网站的对应食谱数据,但无法将数据返回给前端。

测试时使用用户名"John",前端收到空对象,后端控制台显示Promise { <pending> }或仅能在终端看到响应。请问我哪里出错了,为什么会出现Promise pending状态?

前端代码

export const FindUsername = () => {
    const usernameRef = useRef(null)
    const [ username, setUsername ] = useState('');
    const handleClick = async () => {
        setUsername(usernameRef.current.value);
        const response = await axios.get(`http://localhost:3001/user/${username}`)
            .then(res => {
                //console.log(res);
                console.log(res)
            })
        console.log(response)
    }
    return (
        <Stack direction="row">
            <TextField id="outlined-basic" label="Username" variant="outlined" inputRef={usernameRef}/>
            <Button variant="contained" onClick={handleClick}>Find User {username}</Button>
        </Stack>
    );
}

后端爬取模块代码

const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');

const searchWithUsername = async (username) => {
    const targetURL = "https://www.xxxxxxx.com/profile/" + username + "/recipes";
    const {data} = await axios.get(targetURL);
    const recipes = [];
    const $ = cheerio.load(data);
    $('.css-1xwc2tk').each((index, element) => {
        const recipe = $(element).find('.recipe_title').text()
        recipes.push(recipe)
    })
    return recipes;
}

module.exports = searchWithUsername;

后端路由代码

router.get('/', function(req, res, next) {
    const username = req.user_config.user;
    console.log('Got body:', req.user_config.user);
    console.log(searchWithUsername(username));
    res.type('application/json')
    //res.send("OK")
    res.send(searchWithUsername(username).then());
    //res.sendStatus(200);
});

问题分析与修复方案

核心问题:异步代码未正确处理+路由参数匹配错误

  1. searchWithUsername是异步函数,调用后返回Promise。你直接打印Promise或通过searchWithUsername(username).then()传值给res.send,没有等待异步操作完成就返回响应,导致前端收到空数据,后端显示Promise { <pending> }。
  2. 前端通过URL路径传递用户名,但后端错误地从req.user_config.user获取参数,无法拿到正确的用户名,爬取路径无效。

修复步骤

1. 修复后端路由的异步处理与参数获取

将路由处理函数改为异步函数,用await等待爬取完成,同时从URL参数中正确获取用户名:

// 匹配前端请求的/user/:username路径
router.get('/user/:username', async function(req, res, next) {
    const username = req.params.username; // 从URL参数中读取用户名
    console.log('Got username:', username);
    
    try {
        // 等待异步爬取完成
        const recipes = await searchWithUsername(username);
        console.log(recipes); // 打印实际爬取的食谱数组
        res.type('application/json');
        res.send(recipes); // 返回有效数据给前端
    } catch (error) {
        console.error('爬取或请求失败:', error);
        res.status(500).send({ error: '无法获取食谱数据' }); // 错误处理
    }
});

2. 优化前端代码(冗余写法修正+避免旧值问题)

前端同时混用await和.then()写法冗余,且setUsername是异步操作,直接用username拼接URL可能拿到旧值,建议修正:

export const FindUsername = () => {
    const usernameRef = useRef(null)
    const [ username, setUsername ] = useState('');
    const handleClick = async () => {
        const inputUsername = usernameRef.current.value;
        setUsername(inputUsername);
        
        try {
            // 直接使用inputUsername避免异步更新延迟问题
            const response = await axios.get(`http://localhost:3001/user/${inputUsername}`);
            console.log('后端返回数据:', response.data);
            // 这里可以添加数据处理逻辑,比如存储到state
        } catch (error) {
            console.error('请求失败:', error);
        }
    }
    return (
        <Stack direction="row">
            <TextField id="outlined-basic" label="Username" variant="outlined" inputRef={usernameRef}/>
            <Button variant="contained" onClick={handleClick}>Find User {username}</Button>
        </Stack>
    );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:27:09