如何实现实时获取数据库新增商品而不刷新页面

来源:Nodejs社区作者:IT小魔仙头衔:程序员
导读:本期聚焦于小伙伴创作的《如何实现实时获取数据库新增商品而不刷新页面》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何实现实时获取数据库新增商品而不刷新页面》有用,将其分享出去将是对创作者最好的鼓励。

在电商、零售类业务场景中,实时感知数据库新增的商品信息并同步到前端页面,是提升用户交互体验的重要功能。传统的页面刷新方式不仅操作繁琐,还会造成不必要的资源消耗,因此需要采用更高效的实时数据同步方案。

常见实现方案对比

目前主流的实现实时获取数据库新增商品的方案有以下几种,各自的特性如下:

方案名称实时性服务器压力实现难度
前端短轮询
前端长轮询
WebSocket推送
数据库变更监听+消息队列

方案一:前端短轮询实现

短轮询是最简单的实现方式,前端按照固定时间间隔向服务端发送请求,查询是否有新增商品。这种方式实现门槛低,但是实时性依赖轮询间隔,间隔太短会增加服务器压力,间隔太长又无法满足实时需求。

前端代码示例

使用原生JavaScript实现定时请求:

// 定义查询新增商品的接口地址
const queryUrl = 'http://ipipp.com/api/product/new';
// 定义上次查询到的最新商品ID,初始为0
let lastProductId = 0;

// 封装查询函数
function queryNewProduct() {
  // 拼接请求参数,携带上次最新商品ID,避免重复查询
  fetch(`${queryUrl}?last_id=${lastProductId}`)
    .then(response => response.json())
    .then(data => {
      if (data.code === 0 && data.data.length > 0) {
        // 处理新增商品数据,渲染到页面
        renderProductList(data.data);
        // 更新最新商品ID
        lastProductId = data.data[data.data.length - 1].id;
      }
    })
    .catch(err => {
      console.error('查询新增商品失败', err);
    });
}

// 初始查询一次
queryNewProduct();
// 每3秒查询一次
setInterval(queryNewProduct, 3000);

// 渲染商品列表的函数
function renderProductList(productList) {
  const container = document.getElementById('product-container');
  productList.forEach(item => {
    const div = document.createElement('div');
    div.className = 'product-item';
    div.innerHTML = `
      <h3>${item.name}</h3>
      <p>价格:${item.price}元</p>
      <p>上架时间:${item.create_time}</p>
    `;
    container.prepend(div);
  });
}

后端接口示例(Node.js + Express)

后端需要提供查询新增商品的接口,根据传入的last_id返回大于该ID的商品数据:

const express = require('express');
const app = express();
const mysql = require('mysql2/promise');

// 创建数据库连接池
const pool = mysql.createPool({
  host: '127.0.0.1',
  user: 'root',
  password: '123456',
  database: 'product_db',
  waitForConnections: true,
  connectionLimit: 10
});

// 查询新增商品接口
app.get('/api/product/new', async (req, res) => {
  try {
    const lastId = parseInt(req.query.last_id) || 0;
    // 查询ID大于lastId的商品,按ID升序排列
    const [rows] = await pool.query(
      'SELECT id, name, price, create_time FROM product WHERE id > ? ORDER BY id ASC',
      [lastId]
    );
    res.json({
      code: 0,
      data: rows
    });
  } catch (err) {
    console.error('查询商品失败', err);
    res.json({
      code: 1,
      msg: '查询失败'
    });
  }
});

app.listen(3000, () => {
  console.log('服务启动在3000端口');
});

方案二:WebSocket实时推送

WebSocket可以在客户端和服务端之间建立持久连接,服务端可以主动往客户端推送数据,实时性远高于轮询,也减少了不必要的请求消耗。适合对实时性要求较高的场景。

服务端实现(Node.js + ws模块)

服务端需要监听数据库的新增商品事件,当有新商品插入时,推送给所有连接的客户端:

const WebSocket = require('ws');
const mysql = require('mysql2/promise');
const express = require('express');
const app = express();

// 创建WebSocket服务
const wss = new WebSocket.Server({ port: 8080 });

// 数据库连接池
const pool = mysql.createPool({
  host: '127.0.0.1',
  user: 'root',
  password: '123456',
  database: 'product_db'
});

// 监听WebSocket连接
wss.on('connection', (ws) => {
  console.log('有客户端连接');
  ws.on('close', () => {
    console.log('客户端断开连接');
  });
});

// 模拟数据库新增商品的监听,实际场景可以结合数据库的binlog监听或者消息队列实现
// 这里用定时模拟新增商品,实际业务中替换为真实的数据库变更监听逻辑
setInterval(async () => {
  try {
    // 模拟插入一条新商品
    const [result] = await pool.query(
      'INSERT INTO product (name, price, create_time) VALUES (?, ?, NOW())',
      [`测试商品${Date.now()}`, Math.floor(Math.random() * 100) + 10]
    );
    const newProductId = result.insertId;
    // 查询新增的商品详情
    const [rows] = await pool.query(
      'SELECT id, name, price, create_time FROM product WHERE id = ?',
      [newProductId]
    );
    // 推送给所有连接的客户端
    wss.clients.forEach(client => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify({
          type: 'new_product',
          data: rows[0]
        }));
      }
    });
  } catch (err) {
    console.error('新增商品失败', err);
  }
}, 5000);

app.listen(3000, () => {
  console.log('HTTP服务启动在3000端口');
});

前端WebSocket接收示例

前端建立WebSocket连接,接收服务端推送的新增商品数据并渲染:

// 建立WebSocket连接
const ws = new WebSocket('ws://127.0.0.1:8080');

ws.onopen = () => {
  console.log('WebSocket连接成功');
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  if (message.type === 'new_product') {
    // 处理新增商品数据
    renderNewProduct(message.data);
  }
};

ws.onerror = (err) => {
  console.error('WebSocket连接出错', err);
};

ws.onclose = () => {
  console.log('WebSocket连接关闭');
};

// 渲染单个新增商品
function renderNewProduct(product) {
  const container = document.getElementById('product-container');
  const div = document.createElement('div');
  div.className = 'product-item new-product';
  div.innerHTML = `
    <h3>${product.name}</h3>
    <p>价格:${product.price}元</p>
    <p>上架时间:${product.create_time}</p>
    <span class="new-tag">新品</span>
  `;
  container.prepend(div);
}

方案三:数据库变更监听结合消息队列

对于大型项目,可以采用监听数据库变更事件(比如MySQL的binlog、PostgreSQL的NOTIFY)结合消息队列的方案,当数据库有新增商品操作时,触发事件发送到消息队列,服务端消费消息后推送给前端,这种方式解耦了业务和推送逻辑,扩展性更强。

核心流程如下:

  • 配置数据库开启变更日志,比如MySQL开启binlog
  • 使用Canal等中间件监听数据库binlog,过滤出product表的插入操作
  • 将新增商品的信息发送到消息队列(如RabbitMQ、Kafka)
  • 后端服务消费消息队列中的消息,通过WebSocket推送给前端

方案选择建议

如果是小型项目或者实时性要求不高,优先选择前端短轮询,实现成本最低;如果是中型项目,对实时性有一定要求,选择WebSocket推送方案即可;如果是大型分布式项目,建议采用数据库变更监听结合消息队列的方案,方便后续扩展和维护。

在实际开发中,还需要考虑断线重连、消息去重、推送鉴权等细节问题,保障功能的稳定性和可靠性。

WebSocket数据库监听前端轮询实时数据推送修改时间:2026-07-23 21:45:49

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。