Javascript 在函数内初始化nodejs全局变量并使其等同于在函数外调用它

Javascript 在函数内初始化nodejs全局变量并使其等同于在函数外调用它,javascript,node.js,variables,scope,global-variables,Javascript,Node.js,Variables,Scope,Global Variables,所以当涉及到nodejs时,我对作用域有一些问题。我想知道如何在全局空间中初始化变量,在函数(私有范围)中初始化它,然后在类中的任何地方调用它时,使它等于在私有范围中初始化它的值。我注意到的一件事是,尽管可以在私有范围内使用变量,但当在该函数外再次调用该变量时,它将变为未定义。如何返回私有时初始化的相同函数?这不是我发布的代码,而是一个例子,以防图片不清晰 let name; class blah { static blablah() { name = josh;

所以当涉及到nodejs时,我对作用域有一些问题。我想知道如何在全局空间中初始化变量,在函数(私有范围)中初始化它,然后在类中的任何地方调用它时,使它等于在私有范围中初始化它的值。我注意到的一件事是,尽管可以在私有范围内使用变量,但当在该函数外再次调用该变量时,它将变为未定义。如何返回私有时初始化的相同函数?这不是我发布的代码,而是一个例子,以防图片不清晰

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
    }
}
解决方案:确保返回承诺,以便稍后在调用异步函数时在程序中运行该函数

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”(用引号括起来)


一种方法是使您的
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
})();

代码的第一个问题是
josh
不在引号中<代码>约什是
未定义的
;你的意思是“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
    在普通异步回调中没有任何用处。没有人能捕捉到这个错误,因此永远不应该使用它。你需要真正的错误处理。依我看,在那种情况下,你不应该写那行代码

  • returngenesis没有任何有用的功能。这只是从
    fs.readFile()
    回调返回,其中
    fs.readFile()
    的内部将忽略任何返回值。这不会从更高级别的函数返回

  • jsonChain=JSON.parse(数据)
    确实成功地分配给了范围更大的变量,但是任何试图使用
    jsonChain
    变量的代码都不知道该变量何时被分配了值,因为
    fs.readFile()
    是异步的,并且在将来某个不确定的时间调用它的回调。因此,如果您看到
    jsonChain
    没有值,那是因为您在赋值之前查看变量。基本上,这是一种反模式。在node.js中,您不能以这种方式使用异步代码编程。相反,您需要在回调中使用异步值,或者需要从回调中调用某个函数并传递该值。只有在这种情况下,您才知道该值何时可用

  • 如果这里的顶级问题是您试图返回异步检索到的一些值,那么您不能直接在Javascript中这样做。您可以阅读其中的所有内容,其中解释了您必须使用回调、承诺或事件将异步值传递回调用方


  • 现在您已经添加了真正的代码,这里有许多问题

  • if(err)throw err
    在普通异步回调中没有任何用处。没有人能捕捉到这个错误,因此永远不应该使用它。你需要真正的错误处理。依我看,在那种情况下,你不应该写那行代码

  • returngenesis没有任何有用的功能。这只是从
    fs.readFile()
    回调返回,其中
    fs.readFile()
    的内部将忽略任何返回值。这不会从更高级别的函数返回

  • jsonChain=JSON.parse(数据)
    确实成功地分配给了范围更大的变量,但是任何试图使用
    jsonChain
    变量的代码都不知道该变量何时被分配了值,因为
    fs.readFile()
    是异步的,并且在将来某个不确定的时间调用它的回调。因此,如果您看到
    jsonChain
    没有值,那是因为您在赋值之前查看变量。基本上,这是一种反模式。在node.js中,您不能以这种方式使用异步代码编程。相反,您需要在回调中使用异步值,或者需要从回调中调用某个函数并传递该值。只有在这种情况下,您才知道该值何时可用

  • 如果这里的顶级问题是您试图返回异步检索到的一些值,那么您不能直接在Javascript中这样做。您可以阅读其中的所有内容,其中解释了您必须使用回调、承诺或事件将异步值传递回调用方


  • 假设这是真的,我尝试使用的上下文并不完全使用引号,我将在一秒钟内加载我的上下文,让您看看我做错了什么,并希望为像我这样的新加入node insight
    class Blockchain{constructor(){this.chain=[Blockchain.getGenesis()];console.log(Blockchain.getGenesis())的人提供帮助}//使用已发布的函数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;});//如果我将return放在这里,它具有相同的未定义效果
    }请考虑更新yo