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
额外优化建议
- 变量名尽量避免重复(比如原代码中
games.forEach((games) => {的命名混淆问题) - 错误处理环节记得给客户端返回明确的错误响应,避免请求超时
- 原代码中
openHomeTotal的赋值存在疑似笔误,已在修改后的代码中修正
内容的提问来源于stack exchange,提问作者G. Boyce
相关产品推荐
相关产品推荐

