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

Handlebars渲染电影数据重复问题求助(附代码)

问题分析与修复思路

核心问题排查

首先看你的代码,存在几个明显的问题点,直接导致重复渲染:

1. Handlebars变量名不匹配

你在路由中传递给模板的变量是generatedHTMLArrayFavorites,但Handlebars模板里遍历的却是generatedHTMLArray——变量名完全不一致,这要么导致渲染空数据,要么如果模板里的变量名是笔误,实际代码中存在其他重复赋值逻辑,都会引发异常渲染。

2. 中间件逻辑冗余且可能导致数据累加

你的中间件每次请求都会调用getMovieHTMLArrayFavorites()获取数据,即使session中已经存在缓存。如果getMovieHTMLArrayFavorites()内部是用全局数组累加数据(比如每次调用都往同一个数组push电影),而非每次从JSON文件重新读取并生成新数组,就会导致数组里的元素越来越多,重复渲染。

3. Session缓存逻辑不合理

你先获取新数据存到res.locals,再判断session是否为空,为空才存session。但路由里又直接取session中的旧数据——如果session已经存在,中间件获取的新数据完全没用到,既无法更新收藏列表,还可能因为session里的数据本身就是重复的,一直重复渲染。


具体修复步骤

步骤1:修正Handlebars变量名

把模板里的遍历变量改成和路由传递的一致:

{{#each generatedHTMLArrayFavorites}}
  {{{this}}}
{{/each}}

步骤2:优化中间件逻辑

根据你的需求选择两种方案:

方案A:需要缓存收藏列表(不实时更新)

只有当session中没有数据时,才去获取并缓存,避免重复调用可能导致的数据累加:

const FavoriteMoviesArray = async (req, res, next) => {
  if (!req.session.generatedHTMLArrayFavorites) {
    // 仅首次请求时获取数据
    const generatedHTMLArrayFavorites = await movieContainerCreator.getMovieHTMLArrayFavorites();
    // 可选:对数组去重(根据电影ID等唯一标识)
    const uniqueMovies = [...new Map(generatedHTMLArrayFavorites.map(item => [item.movieId, item])).values()];
    req.session.generatedHTMLArrayFavorites = uniqueMovies;
    res.locals.generatedHTMLArrayFavorites = uniqueMovies;
  } else {
    // 复用session缓存的数据
    res.locals.generatedHTMLArrayFavorites = req.session.generatedHTMLArrayFavorites;
  }
  next();
};

方案B:需要实时更新收藏列表

放弃session缓存,每次请求都重新获取最新数据,并确保数据去重:

const FavoriteMoviesArray = async (req, res, next) => {
  const generatedHTMLArrayFavorites = await movieContainerCreator.getMovieHTMLArrayFavorites();
  // 强制去重,避免JSON文件或函数内部的重复数据
  const uniqueMovies = [...new Map(generatedHTMLArrayFavorites.map(item => [item.movieId, item])).values()];
  res.locals.generatedHTMLArrayFavorites = uniqueMovies;
  next();
};

步骤3:修复路由逻辑

路由直接使用res.locals中的数据,保持逻辑统一:

app.get("/Favorite.html", redirectLogin, FavoriteMoviesArray, async function (req, res) {
  try {
    res.render("Favorite", { generatedHTMLArrayFavorites: res.locals.generatedHTMLArrayFavorites });
  } catch (error) {
    console.error("Error:", error);
    res.status(500).send("Internal Server Error");
  }
});

步骤4:检查getMovieHTMLArrayFavorites()实现

确保这个函数每次都是从JSON文件重新读取并生成新数组,而不是往全局数组里追加元素。比如:

// 错误示例(累加数据)
let globalMovies = [];
async function getMovieHTMLArrayFavorites() {
  const data = await fs.readJSON('favorites.json');
  globalMovies.push(...data); // 每次调用都累加
  return globalMovies.map(movie => generateHTML(movie));
}

// 正确示例(每次生成新数组)
async function getMovieHTMLArrayFavorites() {
  const data = await fs.readJSON('favorites.json');
  return data.map(movie => generateHTML(movie)); // 每次返回全新数组
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:43:20