在函数内初始化一个nodejs全局变量并让它等同于在外部调用它
initializing a nodejs global variable within a function and having it equate the same calling it outside
所以当涉及到 nodejs 时,我在范围方面遇到了一些问题。我想知道如何在全局 space 中初始化变量,在函数(私有范围)中初始化它,然后在 class。我注意到的一件事是,虽然您可以在私有范围内使用该变量,但当它在该函数之外再次调用时,它只会变成未定义的。我怎样才能 return 在私有时初始化相同的函数?这不是我发布的代码,而是一个示例,以防图片不清晰
let name;
class blah {
static blablah() {
name = josh;
}
console.log(name);
//this will return undefined and not josh
}
我在我的环境中需要什么:
let genesis;
let jsonChain;
class Blockchain {
constructor() {
//this.chain = [Blockchain.getGenesis()];
console.log(Blockchain.getGenesis());
}
//down the file we find the issued function...
static getGenesis() {
fs.readFile(jsonRoute, 'utf-8', function(err, data) {
if (err) throw err;
jsonChain = JSON.parse(data);
genesis = jsonChain.blocks[0].GENESIS_DATA;
return genesis;
});
//returning here instead inside the callback also yields undefined
//I want to be able to access my contents from json file through
//the genesis variable which is global when I return this function
//but I cannot reach the contents of the callback
}
}
解决方案:确保 return 承诺,以便异步函数稍后在您的程序中运行。
let genesis;
let jsonChain;
class Blockchain {
constructor() {
this.chain = [Blockchain.getGenesis()];
console.log(Blockchain.getGenesis().then(function(genesisData) {
console.log(genesisData); // Genesis block data is here.
}, function(err) {
// This only runs if there was an error.
console.log(err);
}));
}
//down the file we find the solved function...
static getGenesis() {
return new Promise(function(resolve, reject) {
fs.readFile(jsonRoute, 'utf-8', function(err, data) {
if(err) return reject(err);
const jsonChain = JSON.parse(data);
resolve(jsonChain.blocks[0].GENESIS_DATA);
});
});
}
}
module.exports = Blockchain;
您的代码的第一个问题是 josh
不在引号中。 josh
是 undefined
;您是指 'josh'
(引号中)吗?
一种方法是让您的 getGenesis()
函数 async
,这样您就可以等待它完成为 genesis
分配正确的值。这需要将所有内容包装在匿名 async
函数中:
(async () => {
const fs = require('fs');
let genesis;
let jsonChain;
class Blockchain {
constructor() {
this.chain = [Blockchain.getGenesis()];
console.log(Blockchain.getGenesis());
}
static async getGenesis() {
jsonChain = JSON.parse(await fs.promises.readFile(jsonRoute, 'utf-8'));
genesis = jsonChain.blocks[0].GENESIS_DATA;
}
}
console.log(genesis); // undefined D:
await Blockchain.getGenesis();
console.log(genesis); // not undefined :D
})();
现在您已经添加了真正的代码,其中说明了许多问题。
if (err) throw err
在普通异步回调中没有任何用处。没有人可以捕获该错误,因此永远不应该使用它。你需要真正的错误处理。 IMO,在那种情况下永远不应该写那行代码。
return genesis;
没有任何用处。这只是 return 从 fs.readFile()
回调返回,其中 fs.readFile()
的内部忽略任何 return 值。这不是来自更高级别的功能return。
jsonChain = JSON.parse(data);
确实成功地分配给了更高范围的变量,但是任何试图使用 jsonChain
变量的代码都不知道它何时被赋值,因为fs.readFile()
是异步的,并在未来某个不确定的时间调用其回调。所以,如果您看到 jsonChain
没有值,那是因为您在变量被赋值之前查看它。基本上,这是一种反模式。在 node.js 中,您不能以这种方式使用异步代码进行编程。相反,您需要在回调中使用异步值,或者您需要从回调中调用某个函数并将值传递给它。只有在这种情况下,您才知道该值何时可用。
如果这里的顶级问题是您正在尝试 return 您异步检索的某个值,那么您不能直接在 Javascript 中执行此操作。您可以阅读所有关于 here 的内容,其中解释了您必须通过回调、承诺将异步值传回给调用者,或者您也可以使用事件。
所以当涉及到 nodejs 时,我在范围方面遇到了一些问题。我想知道如何在全局 space 中初始化变量,在函数(私有范围)中初始化它,然后在 class。我注意到的一件事是,虽然您可以在私有范围内使用该变量,但当它在该函数之外再次调用时,它只会变成未定义的。我怎样才能 return 在私有时初始化相同的函数?这不是我发布的代码,而是一个示例,以防图片不清晰
let name;
class blah {
static blablah() {
name = josh;
}
console.log(name);
//this will return undefined and not josh
}
我在我的环境中需要什么:
let genesis;
let jsonChain;
class Blockchain {
constructor() {
//this.chain = [Blockchain.getGenesis()];
console.log(Blockchain.getGenesis());
}
//down the file we find the issued function...
static getGenesis() {
fs.readFile(jsonRoute, 'utf-8', function(err, data) {
if (err) throw err;
jsonChain = JSON.parse(data);
genesis = jsonChain.blocks[0].GENESIS_DATA;
return genesis;
});
//returning here instead inside the callback also yields undefined
//I want to be able to access my contents from json file through
//the genesis variable which is global when I return this function
//but I cannot reach the contents of the callback
}
}
解决方案:确保 return 承诺,以便异步函数稍后在您的程序中运行。
let genesis;
let jsonChain;
class Blockchain {
constructor() {
this.chain = [Blockchain.getGenesis()];
console.log(Blockchain.getGenesis().then(function(genesisData) {
console.log(genesisData); // Genesis block data is here.
}, function(err) {
// This only runs if there was an error.
console.log(err);
}));
}
//down the file we find the solved function...
static getGenesis() {
return new Promise(function(resolve, reject) {
fs.readFile(jsonRoute, 'utf-8', function(err, data) {
if(err) return reject(err);
const jsonChain = JSON.parse(data);
resolve(jsonChain.blocks[0].GENESIS_DATA);
});
});
}
}
module.exports = Blockchain;
您的代码的第一个问题是 josh
不在引号中。 josh
是 undefined
;您是指 'josh'
(引号中)吗?
一种方法是让您的 getGenesis()
函数 async
,这样您就可以等待它完成为 genesis
分配正确的值。这需要将所有内容包装在匿名 async
函数中:
(async () => {
const fs = require('fs');
let genesis;
let jsonChain;
class Blockchain {
constructor() {
this.chain = [Blockchain.getGenesis()];
console.log(Blockchain.getGenesis());
}
static async getGenesis() {
jsonChain = JSON.parse(await fs.promises.readFile(jsonRoute, 'utf-8'));
genesis = jsonChain.blocks[0].GENESIS_DATA;
}
}
console.log(genesis); // undefined D:
await Blockchain.getGenesis();
console.log(genesis); // not undefined :D
})();
现在您已经添加了真正的代码,其中说明了许多问题。
if (err) throw err
在普通异步回调中没有任何用处。没有人可以捕获该错误,因此永远不应该使用它。你需要真正的错误处理。 IMO,在那种情况下永远不应该写那行代码。return genesis;
没有任何用处。这只是 return 从fs.readFile()
回调返回,其中fs.readFile()
的内部忽略任何 return 值。这不是来自更高级别的功能return。jsonChain = JSON.parse(data);
确实成功地分配给了更高范围的变量,但是任何试图使用jsonChain
变量的代码都不知道它何时被赋值,因为fs.readFile()
是异步的,并在未来某个不确定的时间调用其回调。所以,如果您看到jsonChain
没有值,那是因为您在变量被赋值之前查看它。基本上,这是一种反模式。在 node.js 中,您不能以这种方式使用异步代码进行编程。相反,您需要在回调中使用异步值,或者您需要从回调中调用某个函数并将值传递给它。只有在这种情况下,您才知道该值何时可用。如果这里的顶级问题是您正在尝试 return 您异步检索的某个值,那么您不能直接在 Javascript 中执行此操作。您可以阅读所有关于 here 的内容,其中解释了您必须通过回调、承诺将异步值传回给调用者,或者您也可以使用事件。