服务器刷新时重复创建Blockchain对象,无法编辑数据如何解决?
解决Blockchain实例反复初始化的问题
核心原因
服务器每次重启(比如代码变更触发自动重启、模块被重复加载)都会重新执行文件内的代码,导致Blockchain实例被重新创建,之前的链数据全部丢失。
具体解决方法
1. 把实例放在模块顶层,利用Node.js模块单例特性
Node.js模块默认是单例加载的,只要将Blockchain实例定义在模块的顶层作用域(而非请求处理函数、路由回调内部),模块仅在第一次被引入时初始化实例,后续复用该实例。
示例代码:
// blockchain.js class Blockchain { constructor() { this.chain = []; this.pendingTransactions = []; // 初始化创世区块等逻辑 } addTransaction(tx) { this.pendingTransactions.push(tx); } } // 顶层作用域创建实例,模块加载时仅执行一次 const blockchainInstance = new Blockchain(); module.exports = blockchainInstance;
在服务器文件中引入复用:
// server.js const express = require('express'); const blockchainInstance = require('./blockchain'); const app = express(); // 路由直接调用已有实例的方法 app.post('/add-transaction', (req, res) => { blockchainInstance.addTransaction(req.body); res.send('交易已添加至待处理队列'); }); app.listen(3000, () => console.log('服务器启动完成'));
2. 禁用不必要的自动重启触发
如果使用nodemon这类自动重启工具,若编辑操作会修改被监听的文件(比如本地存储的区块链数据文件),会触发服务器重启。可通过配置忽略数据文件解决:
在项目根目录创建nodemon.json:
{ "ignore": ["data/*.json", "*.log"] }
3. 持久化区块链数据
通过本地文件、数据库持久化链数据,即使服务器重启,实例也能恢复之前的状态:
const fs = require('fs').promises; const path = require('path'); class Blockchain { constructor() { this.dataPath = path.join(__dirname, 'blockchain-data.json'); this.initChain(); } async initChain() { try { const savedData = await fs.readFile(this.dataPath, 'utf8'); const parsedData = JSON.parse(savedData); this.chain = parsedData.chain; this.pendingTransactions = parsedData.pendingTransactions; } catch (err) { // 文件不存在时初始化创世区块 this.chain = [this.createGenesisBlock()]; this.pendingTransactions = []; } } async saveChain() { const data = JSON.stringify({ chain: this.chain, pendingTransactions: this.pendingTransactions }); await fs.writeFile(this.dataPath, data); } // 执行修改链的操作后调用保存方法 async mineBlock() { // 挖矿逻辑... await this.saveChain(); } }
内容的提问来源于stack exchange,提问作者Naman Vijay
相关产品推荐
相关产品推荐

