如果脚本文件没有直接运行,Nodejs需要变量undefined吗?

时间:2018-03-09 08:22:10

标签: node.js parallel-processing require

我为问题的措辞道歉 - 总结一个问题有点困难 - 如果你能澄清,请随时编辑它。此外,这是一个非常复杂和冗长的查询 - 感谢所有那些花时间阅读它的人!

我有4个文件(与项目根目录树一起列出)作为项目的一部分我的目标是抓住区块链并利用多个核心来完成工作:

  1. ./ main.js
  2. ./ scraper.js
  3. ./ API / api.js
  4. ./ API / litecoin_api.js
  5. main.js

    const { scraper } = require('./scraper.js')
    const blockchainCli = process.env.BLOCKSCRAPECLI || 'litecoin-cli'
    
    const client = (args) => {
      // create child process which returns a promise which resolves after
      // data has finished buffering from locally hosted node using cli
      let child = spawn(`${blockchainCli} ${args.join(' ')}`, {
        shell: true
      })
      // ... wrap command in a promise here, etc
    }
    
    const main = () => {
      // count cores, spawn a worker per core using node cluster, add
      // message handlers, then begin scraping blockchain with each core...
      scraper(blockHeight)
    }
    
    main()
    
    module.exports = {
      client,
      blockchainCli
    }
    

    scraper.js

    const api = require('./api/api.js')
    const scraper = async (blockHeight) => {
      try {
        let blockHash = await api.getBlockHashByHeight(blockHeight)
        let block = await api.getBlock(blockHash)
        // ... etc, scraper tested and working, writes to shared writeStream
    }
    
    module.exports = {
      scraper
    }
    

    api.js

    const { client, blockchainCli } = require('../main.js')
    const litecoin = require('./litecoin_api')
    
    let blockchain = undefined
    
    if (blockchainCli === 'litecoin-cli' || blockchainCli === 'bitcoin-cli') {
      blockchain = litecoin
    }
    // PROBLEM HERE: blockchainCli (and client) are both undefined if and
    // only if running scraper from main.js (but not if running scraper
    // from scraper.js)
    
    const decodeRawTransaction = (txHash) => {
      return client([blockchain.decodeRawTransaction, txHash])
    }
    
    const getBlock = (blockhash) => {
      return client([blockchain.getBlock, blockhash])
    }
    
    const getBlockHashByHeight = (height) => {
      return client([blockchain.getBlockHash, height])
    }
    
    const getInfo = () => {
      return client([blockchain.getInfo])
    }
    
    const getRawTransaction = (txHash, verbose = true) => {
      return client([blockchain.getRawTransaction, txHash, verbose])
    }
    
    module.exports = {
      decodeRawTransaction,
      getBlock,
      getBlockHashByHeight,
      getInfo,
      getRawTransaction
    }
    

    所以,我已经把文件中的大部分噪音拿走了,我认为这些文件是必要的,但它是开源的,所以如果你需要更多take a look here

    问题在于,如果我从scraper.js内部开始执行刮刀,比如这样做:scraper(1234567)它就像魅力一样,并将预期数据输出到csv文件。

    但是,如果我从main.js文件中启动刮刀,我会收到此错误:

    Cannot read property 'getBlockHash' of undefined
        at Object.getBlockHashByHeight (/home/grayedfox/github/blockscrape/api/api.js:19:29)
        at scraper (/home/grayedfox/github/blockscrape/scraper.js:53:31)
        at Worker.messageHandler (/home/grayedfox/github/blockscrape/main.js:81:5)
    

    我不知道为什么在从main.js启动刮刀时,区块链是未定义的。我认为它可能来自解构,但是从示例main.js文件中的第一行周围删除花括号并不会改变任何内容(相同的错误)。

    目前事情有点混乱(在开发这个分支的过程中) - 但现在的基本问题是,我不清楚为什么需求会失败(无法看到main.js中的变量)如果它以下列方式使用:

    • main.js(执行scraper())> scraper.js> api.js

    但如果它运行如下,则不会失败(可以看到main.js中的变量):

    • scraper.js(执行scraper())> api.js

    非常感谢你的时间!

1 个答案:

答案 0 :(得分:1)

main和api之间存在循环依赖关系,每个都需要另一个。 main需要api通过scraper和api直接需要main。这导致事情无法奏效。

您必须通过将公共共享代码放入其自己的模块中来删除循环依赖关系,两者都可以包含它,但不包括包含它的其他模块。它只需要更好的模块化。