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

Express路由中request-promise返回响应重复问题排查

问题诊断与解决方案

我一眼就看出问题所在了——你用来存储解析后数据的那些数组(homeTeam、awayTeam、currOdds、openOdds、mergRecs)是在路由处理函数外部定义的全局变量!

每次收到请求时,你只会往这些数组里追加新数据,却从来没有清空它们。第一次请求时数组是空的,所以返回正常;第二次请求时,上一次的数据还留在数组里,新数据又加进去,自然就出现重复的payload了。而返回"hello world"时没问题,是因为这个字符串每次都是重新生成的,不存在累积的问题。

修复方案

把这些数组的声明移到router.get('/odds/:bid', ...)的回调函数内部,让每次请求都创建全新的空数组,这样就不会累积之前的请求数据了。

修改后的代码如下:

// packages
const express = require('express');
const router = express.Router();
const rp = require('request-promise');

// date logic - 这里可以保留,日期每次请求时重新计算,无问题
var today = new Date();
var d = today.getDate();
var m = today.getMonth()+1; // January is 0!
var y = today.getFullYear();
if(d<10) { d = '0'+d }
if(m<10) { m = '0'+m }
today = y + m + d;

// retrieve specific ocr records
router.get('/odds/:bid', (req,res,next) => {
    // 把所有存储数据的数组移到这里,每次请求初始化空数组
    const homeTeam = [];
    const awayTeam = [];
    const currOdds = [];
    const openOdds = [];
    const mergRecs = [];

    // sports action API connection
    const actionApi = {
        url: `https://api-prod.sprtactn.co/web/v1/scoreboard/${req.params.bid}?date=${today}`,
        json: true
    }

    // home team, away team, opening odds, and closing odds API pull
    rp(actionApi)
    .then((data) => {
        const games = data.games
        games.forEach((game) => { // 变量名改为game,避免和外层games重名,更清晰
            game.teams.forEach((team, i) => {
                if (game.home_team_id == game.teams[i].id) {
                    homeTeam.push({home_team: game.teams[i].full_name});
                } else if (game.away_team_id == game.teams[i].id) {
                    awayTeam.push({away_team: game.teams[i].full_name});
                }
            })
            game.odds.forEach((odd, i) => {
                if (game.odds[i].type == "game" && game.odds[i].book_id == "15") {
                    currOdds.push({
                        currAwayLine: game.odds[i].ml_away,
                        currHomeLine: game.odds[i].ml_home,
                        currAwaySpread: game.odds[i].spread_away,
                        currHomeSpread: game.odds[i].spread_home,
                        currAwayTotal: game.odds[i].total,
                        currHomeTotal: game.odds[i].total,
                        homeMlBets: game.odds[i].ml_home_public,
                        awayMlBets: game.odds[i].ml_away_public,
                        totalOverBets: game.odds[i].total_over_public,
                        totalUnderBets: game.odds[i].total_under_public,
                        spreadHomeBets: game.odds[i].spread_home_public,
                        spreadAwayBets: game.odds[i].spread_away_public
                    })
                } else if (game.odds[i].type == "game" && game.odds[i].book_id == "30") {
                    openOdds.push({
                        openAwayLine: game.odds[i].ml_away,
                        openHomeLine: game.odds[i].ml_home,
                        openAwaySpread: game.odds[i].spread_away,
                        openHomeSpread: game.odds[i].spread_home,
                        openAwayTotal: game.odds[i].total,
                        openHomeTotal: game.odds[i].total
                    })
                }
            })
        })
        for (i = 0; i < homeTeam.length; i++) {
            mergRecs.push({
                homeTeam: homeTeam[i].home_team,
                awayTeam: awayTeam[i].away_team,
                currAwayLine: currOdds[i].currAwayLine,
                currHomeLine: currOdds[i].currHomeLine,
                openAwayLine: openOdds[i].openAwayLine,
                openHomeLine: openOdds[i].openHomeLine,
                currAwaySpread: currOdds[i].currAwaySpread,
                currHomeSpread: currOdds[i].currHomeSpread,
                openAwaySpread: openOdds[i].openAwaySpread,
                openHomeSpread: openOdds[i].openHomeSpread,
                currAwayTotal: currOdds[i].currAwayTotal,
                currHomeTotal: currOdds[i].currHomeTotal,
                openAwayTotal: openOdds[i].openAwayTotal,
                openHomeTotal: openOdds[i].openHomeTotal, // 原代码此处是openAwayTotal,疑似笔误,已修正
                homeMlBets: currOdds[i].homeMlBets,
                awayMlBets: currOdds[i].awayMlBets,
                totalOverBets: currOdds[i].totalOverBets,
                totalUnderBets: currOdds[i].totalUnderBets,
                spreadHomeBets: currOdds[i].spreadHomeBets,
                spreadAwayBets: currOdds[i].spreadAwayBets
            })
        }
        res.send(mergRecs)
    })
    .catch((err) => {
        console.log(err);
        // 新增错误响应,避免客户端长期等待
        res.status(500).send({error: 'Failed to fetch game data'});
    })
})

module.exports = router; // make router exportable

额外优化建议

  1. 变量名尽量避免重复(比如原代码中games.forEach((games) => {的命名混淆问题)
  2. 错误处理环节记得给客户端返回明确的错误响应,避免请求超时
  3. 原代码中openHomeTotal的赋值存在疑似笔误,已在修改后的代码中修正

内容的提问来源于stack exchange,提问作者G. Boyce

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:38:29