nodejs解构变量返回未定义
nodejs destructuring variables returning undefined
所以我在 nodejs 中构建区块链,当我 运行 应用程序时,我的构造函数变量传递未定义,尽管我这样做是为了将变量作为索引文件中的对象传递。下面将显示以下相关文件...
用于发布订阅的 PubNub:
const PubNub = require('pubnub');
const credentials = {
publishKey: 'pub-c-274ab4f3-redacted',
subscribeKey: 'sub-c-fe7d959c-redacted',
secretKey: 'sec-c-cannotDisplay'
};
const CHANNELS = {
TEST: 'TEST',
BLOCKCHAIN: 'BLOCKCHAIN',
TRANSACTION: 'TRANSACTION'
};
class PubSub {
constructor({ blockchain, transactionPool, wallet }) {
this.blockchain = blockchain;
this.transactionPool = transactionPool;
this.wallet = wallet;
this.pubnub = new PubNub(credentials);
//where you put uuid
this.pubnub.subscribe({ channels: Object.values(CHANNELS) });
this.pubnub.addListener(this.listener());
}
broadcastChain() {
this.publish({
channel: CHANNELS.BLOCKCHAIN,
message: JSON.stringify(this.blockchain.chain)
});
}
broadcastTransaction(transaction) {
this.publish({
channel: CHANNELS.TRANSACTION,
message: JSON.stringify(transaction)
});
}
subscribeToChannels() {
this.pubnub.subscribe({
channels: [Object.values(CHANNELS)]
});
}
listener() {
return {
message: messageObject => {
const { channel, message } = messageObject;
console.log(`Message received. Channel: ${channel}. Message: ${message}`);
const parsedMessage = JSON.parse(message);
switch(channel) {
case CHANNELS.BLOCKCHAIN:
this.blockchain.replaceChain(parsedMessage, true, () => {
this.transactionPool.clearBlockchainTransactions(
{ chain: parsedMessage.chain }
);
});
break;
case CHANNELS.TRANSACTION:
if (!this.transactionPool.existingTransaction({
inputAddress: this.wallet.publicKey
})) {
this.transactionPool.setTransaction(parsedMessage);
}
break;
default:
return;
}
}
}
}
publish({ channel, message }) {
// there is an unsubscribe function in pubnub
// but it doesn't have a callback that fires after success
// therefore, redundant publishes to the same local subscriber will be accepted as noisy no-ops
this.pubnub.publish({ message, channel });//channel,message
}
broadcastChain() {
this.publish({
channel: CHANNELS.BLOCKCHAIN,
message: JSON.stringify(this.blockchain.chain)
});
}
broadcastTransaction(transaction) {
this.publish({
channel: CHANNELS.TRANSACTION,
message: JSON.stringify(transaction)
});
}
}
const testPubSub = new PubSub()
{
testPubSub.publish({channel: CHANNELS.TEST, message: 'testing'});
}
module.exports = PubSub;
主要索引:
const bodyParser = require('body-parser');
const express = require('express');
const request = require('request');
const path = require('path');
const Blockchain = require('./blockchain');
const PubSub = require('./app/pubsub');
const TransactionPool = require('./wallet/transaction-pool');
const Wallet = require('./wallet');
const TransactionMiner = require('./app/transaction-miner');
const PubSubNub = require('./app/pubsub.pubnub');
//127.0.0.1:6379
const isDevelopment = process.env.ENV === 'development';
//TRY PUBNUB (comment out)
/*const REDIS_URL = isDevelopment ?
'redis://127.0.0.1:6379' : //try 6379 19289
'redis://h:p602b6838e89da65c8c4d29a6a4f954452d1ece59c10b27a29ebf9808721cb8e2@ec2-35-153-115-238.compute-1.amazonaws.com:9819'//19289
*/
const DEFAULT_PORT = 3000;
const ROOT_NODE_ADDRESS =
`http://localhost:${DEFAULT_PORT}`;
const app = express();
const blockchain = new Blockchain();
const transactionPool = new TransactionPool();
const wallet = new Wallet();
//const pubsub = new PubSub({ blockchain, transactionPool, redisUrl: REDIS_URL });//redis
const pubsub = new PubSubNub({ blockchain, transactionPool, wallet }); // for PubNub //change back to PubSub if issues arise
const transactionMiner = new TransactionMiner({ blockchain, transactionPool, wallet, pubsub });
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'client/dist')));
//endpoint
app.get('/api/blocks', (req, res) => {
res.json(blockchain.chain);
});
app.get('/api/blocks/length', (req, res) => {
res.json(blockchain.chain.length);
});
app.get('/api/blocks/:id', (req, res) => {
const { id } = req.params;
const { length } = blockchain.chain;
const blocksReversed = blockchain.chain.slice().reverse();
let startIndex = (id-1) * 5;
let endIndex = id * 5;
startIndex = startIndex < length ? startIndex : length;
endIndex = endIndex < length ? endIndex : length;
res.json(blocksReversed.slice(startIndex, endIndex));
});
app.post('/api/mine', (req, res) => {
const { data } = req.body;
blockchain.addBlock({ data });
pubsub.broadcastChain();
res.redirect('/api/blocks');
});
app.post('/api/transact', (req, res) => {
const { amount, recipient } = req.body;
let transaction = transactionPool
.existingTransaction({ inputAddress: wallet.publicKey });
try {
if (transaction) {
transaction.update({ senderWallet: wallet, recipient, amount });
} else {
transaction = wallet.createTransaction({
recipient,
amount,
chain: blockchain.chain
});
}
} catch(error) {
return res.status(400).json({ type: 'error', message: error.message });
}
transactionPool.setTransaction(transaction);
pubsub.broadcastTransaction(transaction);
res.json({ type: 'success', transaction });
});
app.get('/api/transaction-pool-map', (req, res) => {
res.json(transactionPool.transactionMap);
});
app.get('/api/mine-transactions', (req, res) => {
transactionMiner.mineTransactions();
res.redirect('/api/blocks');
});
app.get('/api/wallet-info', (req, res) => {
const address = wallet.publicKey;
res.json({
address,
balance: Wallet.calculateBalance({ chain: blockchain.chain, address })
});
});
app.get('/api/known-addresses', (req, res) => {
const addressMap = {};
for (let block of blockchain.chain) {
for (let transaction of block.data) {
const recipient = Object.keys(transaction.outputMap);
recipient.forEach(recipient => addressMap[recipient] = recipient);
}
}
res.json(Object.keys(addressMap));
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'client/dist/index.html'));
});
const syncWithRootState = () => {
request({ url: `${ROOT_NODE_ADDRESS}/api/blocks` }, (error, response, body) => {
if (!error && response.statusCode === 200) {
const rootChain = JSON.parse(body);
console.log('replace chain on a sync with', rootChain);
blockchain.replaceChain(rootChain);
}
});
request({ url: `${ROOT_NODE_ADDRESS}/api/transaction-pool-map` }, (error, response, body) => {
if (!error && response.statusCode === 200) {
const rootTransactionPoolMap = JSON.parse(body);
console.log('replace transaction pool map on a sync with', rootTransactionPoolMap);
transactionPool.setMap(rootTransactionPoolMap);
}
});
};
if (isDevelopment) {
const walletFoo = new Wallet();
const walletBar = new Wallet();
const generateWalletTransaction = ({ wallet, recipient, amount }) => {
const transaction = wallet.createTransaction({
recipient, amount, chain: blockchain.chain
});
transactionPool.setTransaction(transaction);
};
const walletAction = () => generateWalletTransaction({
wallet, recipient: walletFoo.publicKey, amount: 5
});
const walletFooAction = () => generateWalletTransaction({
wallet: walletFoo, recipient: walletBar.publicKey, amount: 10
});
const walletBarAction = () => generateWalletTransaction({
wallet: walletBar, recipient: wallet.publicKey, amount: 15
});
for (let i=0; i<20; i++) {
if (i%3 === 0) {
walletAction();
walletFooAction();
} else if (i%3 === 1) {
walletAction();
walletBarAction();
} else {
walletFooAction();
walletBarAction();
}
transactionMiner.mineTransactions();
}
}
let PEER_PORT;
if (process.env.GENERATE_PEER_PORT === 'true') {
PEER_PORT = DEFAULT_PORT + Math.ceil(Math.random() * 1000);
}
const PORT = process.env.PORT || PEER_PORT || DEFAULT_PORT;
app.listen(PORT, () => {
console.log(`listening at localhost:${PORT}`);
if (PORT !== DEFAULT_PORT) {
syncWithRootState();
}
});
错误日志:
main@goldengates.club [~/public_html/Cypher-Network]# npm run start
> Cypher-Network@1.0.0 start /home/main/public_html/Cypher-Network
> npm run build-client & node index.js
> Cypher-Network@1.0.0 build-client /home/main/public_html/Cypher-Network
> npm run clean && parcel build client/src/index.html --out-dir client/dist
> Cypher-Network@1.0.0 clean /home/main/public_html/Cypher-Network
> rm -rf .cache client/dist
/home/main/public_html/Cypher-Network/app/pubsub.pubnub.js:16
constructor({ blockchain, transactionPool, wallet }) {
^
TypeError: Cannot destructure property 'blockchain' of 'undefined' as it is undefined.
at new PubSub (/home/main/public_html/Cypher-Network/app/pubsub.pubnub.js:16:17)
at Object.<anonymous> (/home/main/public_html/Cypher-Network/app/pubsub.pubnub.js:99:20)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)
at Module.require (internal/modules/cjs/loader.js:1044:19)
at require (internal/modules/cjs/helpers.js:77:18)
at Object.<anonymous> (/home/main/public_html/Cypher-Network/index.js:10:19)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! Cypher-Network@1.0.0 start: `npm run build-client & node index.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the Cypher-Network@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/main/.npm/_logs/2020-03-27T18_49_30_710Z-debug.log
⠋ Building...lscpu: failed to determine number of CPUs: /sys/devices/system/cpu/possible: No such file or directory
✨ Built in 17.71s.
client/dist/src.a02dd135.js.map ⚠️ 1.17 MB 160ms
client/dist/src.a02dd135.js 501.63 KB 17.02s
client/dist/logo.04580eb6.png 50.84 KB 4.37s
client/dist/src.e852c4ed.css.map 957 B 4ms
client/dist/index.html 454 B 457ms
client/dist/src.e852c4ed.css 454 B 4.86s
如果需要我共享继承的文件,请通知。
这里:
class PubSub {
constructor({ blockchain, transactionPool, wallet }) {
这里:
const testPubSub = new PubSub()
因此,对于这个特定的构造函数调用,PubSub
构造函数中的解构相当于
const { blockchain, transactionPool, wallet } = undefined;
你不能这样做,无论是 undefined
还是 null
。您需要使用正确的参数调用 new PubSub(/*...*/)
,或者使用默认参数值。
所以我在 nodejs 中构建区块链,当我 运行 应用程序时,我的构造函数变量传递未定义,尽管我这样做是为了将变量作为索引文件中的对象传递。下面将显示以下相关文件...
用于发布订阅的 PubNub:
const PubNub = require('pubnub');
const credentials = {
publishKey: 'pub-c-274ab4f3-redacted',
subscribeKey: 'sub-c-fe7d959c-redacted',
secretKey: 'sec-c-cannotDisplay'
};
const CHANNELS = {
TEST: 'TEST',
BLOCKCHAIN: 'BLOCKCHAIN',
TRANSACTION: 'TRANSACTION'
};
class PubSub {
constructor({ blockchain, transactionPool, wallet }) {
this.blockchain = blockchain;
this.transactionPool = transactionPool;
this.wallet = wallet;
this.pubnub = new PubNub(credentials);
//where you put uuid
this.pubnub.subscribe({ channels: Object.values(CHANNELS) });
this.pubnub.addListener(this.listener());
}
broadcastChain() {
this.publish({
channel: CHANNELS.BLOCKCHAIN,
message: JSON.stringify(this.blockchain.chain)
});
}
broadcastTransaction(transaction) {
this.publish({
channel: CHANNELS.TRANSACTION,
message: JSON.stringify(transaction)
});
}
subscribeToChannels() {
this.pubnub.subscribe({
channels: [Object.values(CHANNELS)]
});
}
listener() {
return {
message: messageObject => {
const { channel, message } = messageObject;
console.log(`Message received. Channel: ${channel}. Message: ${message}`);
const parsedMessage = JSON.parse(message);
switch(channel) {
case CHANNELS.BLOCKCHAIN:
this.blockchain.replaceChain(parsedMessage, true, () => {
this.transactionPool.clearBlockchainTransactions(
{ chain: parsedMessage.chain }
);
});
break;
case CHANNELS.TRANSACTION:
if (!this.transactionPool.existingTransaction({
inputAddress: this.wallet.publicKey
})) {
this.transactionPool.setTransaction(parsedMessage);
}
break;
default:
return;
}
}
}
}
publish({ channel, message }) {
// there is an unsubscribe function in pubnub
// but it doesn't have a callback that fires after success
// therefore, redundant publishes to the same local subscriber will be accepted as noisy no-ops
this.pubnub.publish({ message, channel });//channel,message
}
broadcastChain() {
this.publish({
channel: CHANNELS.BLOCKCHAIN,
message: JSON.stringify(this.blockchain.chain)
});
}
broadcastTransaction(transaction) {
this.publish({
channel: CHANNELS.TRANSACTION,
message: JSON.stringify(transaction)
});
}
}
const testPubSub = new PubSub()
{
testPubSub.publish({channel: CHANNELS.TEST, message: 'testing'});
}
module.exports = PubSub;
主要索引:
const bodyParser = require('body-parser');
const express = require('express');
const request = require('request');
const path = require('path');
const Blockchain = require('./blockchain');
const PubSub = require('./app/pubsub');
const TransactionPool = require('./wallet/transaction-pool');
const Wallet = require('./wallet');
const TransactionMiner = require('./app/transaction-miner');
const PubSubNub = require('./app/pubsub.pubnub');
//127.0.0.1:6379
const isDevelopment = process.env.ENV === 'development';
//TRY PUBNUB (comment out)
/*const REDIS_URL = isDevelopment ?
'redis://127.0.0.1:6379' : //try 6379 19289
'redis://h:p602b6838e89da65c8c4d29a6a4f954452d1ece59c10b27a29ebf9808721cb8e2@ec2-35-153-115-238.compute-1.amazonaws.com:9819'//19289
*/
const DEFAULT_PORT = 3000;
const ROOT_NODE_ADDRESS =
`http://localhost:${DEFAULT_PORT}`;
const app = express();
const blockchain = new Blockchain();
const transactionPool = new TransactionPool();
const wallet = new Wallet();
//const pubsub = new PubSub({ blockchain, transactionPool, redisUrl: REDIS_URL });//redis
const pubsub = new PubSubNub({ blockchain, transactionPool, wallet }); // for PubNub //change back to PubSub if issues arise
const transactionMiner = new TransactionMiner({ blockchain, transactionPool, wallet, pubsub });
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'client/dist')));
//endpoint
app.get('/api/blocks', (req, res) => {
res.json(blockchain.chain);
});
app.get('/api/blocks/length', (req, res) => {
res.json(blockchain.chain.length);
});
app.get('/api/blocks/:id', (req, res) => {
const { id } = req.params;
const { length } = blockchain.chain;
const blocksReversed = blockchain.chain.slice().reverse();
let startIndex = (id-1) * 5;
let endIndex = id * 5;
startIndex = startIndex < length ? startIndex : length;
endIndex = endIndex < length ? endIndex : length;
res.json(blocksReversed.slice(startIndex, endIndex));
});
app.post('/api/mine', (req, res) => {
const { data } = req.body;
blockchain.addBlock({ data });
pubsub.broadcastChain();
res.redirect('/api/blocks');
});
app.post('/api/transact', (req, res) => {
const { amount, recipient } = req.body;
let transaction = transactionPool
.existingTransaction({ inputAddress: wallet.publicKey });
try {
if (transaction) {
transaction.update({ senderWallet: wallet, recipient, amount });
} else {
transaction = wallet.createTransaction({
recipient,
amount,
chain: blockchain.chain
});
}
} catch(error) {
return res.status(400).json({ type: 'error', message: error.message });
}
transactionPool.setTransaction(transaction);
pubsub.broadcastTransaction(transaction);
res.json({ type: 'success', transaction });
});
app.get('/api/transaction-pool-map', (req, res) => {
res.json(transactionPool.transactionMap);
});
app.get('/api/mine-transactions', (req, res) => {
transactionMiner.mineTransactions();
res.redirect('/api/blocks');
});
app.get('/api/wallet-info', (req, res) => {
const address = wallet.publicKey;
res.json({
address,
balance: Wallet.calculateBalance({ chain: blockchain.chain, address })
});
});
app.get('/api/known-addresses', (req, res) => {
const addressMap = {};
for (let block of blockchain.chain) {
for (let transaction of block.data) {
const recipient = Object.keys(transaction.outputMap);
recipient.forEach(recipient => addressMap[recipient] = recipient);
}
}
res.json(Object.keys(addressMap));
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'client/dist/index.html'));
});
const syncWithRootState = () => {
request({ url: `${ROOT_NODE_ADDRESS}/api/blocks` }, (error, response, body) => {
if (!error && response.statusCode === 200) {
const rootChain = JSON.parse(body);
console.log('replace chain on a sync with', rootChain);
blockchain.replaceChain(rootChain);
}
});
request({ url: `${ROOT_NODE_ADDRESS}/api/transaction-pool-map` }, (error, response, body) => {
if (!error && response.statusCode === 200) {
const rootTransactionPoolMap = JSON.parse(body);
console.log('replace transaction pool map on a sync with', rootTransactionPoolMap);
transactionPool.setMap(rootTransactionPoolMap);
}
});
};
if (isDevelopment) {
const walletFoo = new Wallet();
const walletBar = new Wallet();
const generateWalletTransaction = ({ wallet, recipient, amount }) => {
const transaction = wallet.createTransaction({
recipient, amount, chain: blockchain.chain
});
transactionPool.setTransaction(transaction);
};
const walletAction = () => generateWalletTransaction({
wallet, recipient: walletFoo.publicKey, amount: 5
});
const walletFooAction = () => generateWalletTransaction({
wallet: walletFoo, recipient: walletBar.publicKey, amount: 10
});
const walletBarAction = () => generateWalletTransaction({
wallet: walletBar, recipient: wallet.publicKey, amount: 15
});
for (let i=0; i<20; i++) {
if (i%3 === 0) {
walletAction();
walletFooAction();
} else if (i%3 === 1) {
walletAction();
walletBarAction();
} else {
walletFooAction();
walletBarAction();
}
transactionMiner.mineTransactions();
}
}
let PEER_PORT;
if (process.env.GENERATE_PEER_PORT === 'true') {
PEER_PORT = DEFAULT_PORT + Math.ceil(Math.random() * 1000);
}
const PORT = process.env.PORT || PEER_PORT || DEFAULT_PORT;
app.listen(PORT, () => {
console.log(`listening at localhost:${PORT}`);
if (PORT !== DEFAULT_PORT) {
syncWithRootState();
}
});
错误日志:
main@goldengates.club [~/public_html/Cypher-Network]# npm run start
> Cypher-Network@1.0.0 start /home/main/public_html/Cypher-Network
> npm run build-client & node index.js
> Cypher-Network@1.0.0 build-client /home/main/public_html/Cypher-Network
> npm run clean && parcel build client/src/index.html --out-dir client/dist
> Cypher-Network@1.0.0 clean /home/main/public_html/Cypher-Network
> rm -rf .cache client/dist
/home/main/public_html/Cypher-Network/app/pubsub.pubnub.js:16
constructor({ blockchain, transactionPool, wallet }) {
^
TypeError: Cannot destructure property 'blockchain' of 'undefined' as it is undefined.
at new PubSub (/home/main/public_html/Cypher-Network/app/pubsub.pubnub.js:16:17)
at Object.<anonymous> (/home/main/public_html/Cypher-Network/app/pubsub.pubnub.js:99:20)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)
at Module.require (internal/modules/cjs/loader.js:1044:19)
at require (internal/modules/cjs/helpers.js:77:18)
at Object.<anonymous> (/home/main/public_html/Cypher-Network/index.js:10:19)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! Cypher-Network@1.0.0 start: `npm run build-client & node index.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the Cypher-Network@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/main/.npm/_logs/2020-03-27T18_49_30_710Z-debug.log
⠋ Building...lscpu: failed to determine number of CPUs: /sys/devices/system/cpu/possible: No such file or directory
✨ Built in 17.71s.
client/dist/src.a02dd135.js.map ⚠️ 1.17 MB 160ms
client/dist/src.a02dd135.js 501.63 KB 17.02s
client/dist/logo.04580eb6.png 50.84 KB 4.37s
client/dist/src.e852c4ed.css.map 957 B 4ms
client/dist/index.html 454 B 457ms
client/dist/src.e852c4ed.css 454 B 4.86s
如果需要我共享继承的文件,请通知。
这里:
class PubSub {
constructor({ blockchain, transactionPool, wallet }) {
这里:
const testPubSub = new PubSub()
因此,对于这个特定的构造函数调用,PubSub
构造函数中的解构相当于
const { blockchain, transactionPool, wallet } = undefined;
你不能这样做,无论是 undefined
还是 null
。您需要使用正确的参数调用 new PubSub(/*...*/)
,或者使用默认参数值。