在继续循环之前不等待条件完成的函数

Function not waiting for conditional to finish before continuing loop

我有这个功能,它循环遍历每个新块的交易,然后保存与我的数据库中存储的地址匹配的交易。

块只是对象的数组。

但是,如果一个交易在不同的块中有事件,await ticker.save();会因为某些原因运行在!matchingHash条件完成之前,然后在没有完成的情况下进入下一个块有条件的。

如果交易的所有事件都在同一个块中,则该函数完全可以正常工作,但如果它们在不同的块中,则不会。

这是我现在正在记录的内容,以尝试解决此问题:

11923243
Transaction found, currentBlock: 0x365b5c75d581a74ffb6681f29156e3aca87dd4221419e91434ss4bdd03f67393ee3 11923243
getTransaction, event block, currentBlock 11923243 11923243
getBlock, event block, currentBlock 11923243 11923243
ticker saved
11923244
Transaction found, currentBlock: 0x365b5c75d581a74ffb6681f29156e3aca87dd4221419e91434ss4bdd03f67393ee3 11923244
getTransaction, event block, currentBlock 11923243 11923244
new Transaction, event block, currentBlock 11923243 11923244
New transaction added
getBlock, event block, currentBlock 11923243 11923244
new Transaction, event block, currentBlock 11923243 11923244
error: MongoError: E11000 duplicate key error collection: Cluster0.transactions index: transactionHash_1 dup key: { transactionHash: "0x365b5c75d581a74ffb6681f29156e3aca87dd4221419e91434ss4bdd03f67393ee3" }

函数:

 async function getTransactions() {
    try {
      terminate = false;
    
      const web3 = new Web3(
        new Web3.providers.HttpProvider(
          'http://example.com/rpc'
        )
      );
    
      let lastBlock;
    
      const getLastBlock = await web3.eth.getBlockNumber();
    
      console.log('getLastBlock:', getLastBlock);
    
      const syncing = await web3.eth.isSyncing();
    
      console.log('Syncing status:', syncing);
    
      // Check if the node is still syncing
      if (syncing) {
        lastBlock = syncing.highestBlock;
      } else {
        lastBlock = getLastBlock;
      }
    
      console.log(await web3.eth.getBlockNumber());
    
      // Avoid indexing reorgs by not including the last two days
      lastBlock = lastBlock - 11520;
    
      let currentBlock;
    
      if (
        ticker.contractTransactions.lastFetchedBlock === null ||
        ticker.contractTransactions.lastFetchedBlock === 0
      ) {
        currentBlock = ticker.tickerContracts.map((item) => {
          return item.block;
        });
    
        currentBlock = Math.min(...currentBlock);
      } else {
        currentBlock = ticker.contractTransactions.lastFetchedBlock;
      }
    
      while (currentBlock < lastBlock) {
        console.log(`{currentBlock}`);
    
        for (let i = 0; i < ticker.tickerContracts.length; i++) {
          const contract = new web3.eth.Contract(
            [],
            ticker.tickerContracts[i].address
          );
    
          await contract.getPastEvents(
            'allEvents',
            { fromBlock: currentBlock, toBlock: currentBlock },
            async function (error, events) {
    
            
                if (events && events.length > 0) {
                  function Raw(address, data, eventSignature, topics) {
                    this.address = address;
                    this.data = data;
                    this.eventSignature = eventSignature;
                    this.topics = topics;
                  }
    
                  
          );
        }
    
        ticker.contractTransactions.lastFetchedBlock = currentBlock;
    
        await ticker.save();
        console.log('ticker saved');
    
        if (terminate === true) {
          return 'All function execution has been terminated';
        }
    
        currentBlock++;
      }
    } catch (err) {
      console.log('Error', err);
    
      startupFetch();
      console.log('Calling function to restart fetching...');
    }
    if (terminate === true) {
      return 'All function execution has been terminated';
    }
    
    startupFetch();
    console.log('Calling function to restart fetching...');
      }

您正在混合回调 API 和承诺 API,这永远不会有好结果。

如果您将函数作为回调传递,它不应该是 async,也不会被 awaited。

但是 getPastEvents 已经 returns 一个承诺,所以根本没有理由使用任何回调!

而不是这个...

await contract.getPastEvents(
  'allEvents',
  { fromBlock: currentBlock, toBlock: currentBlock },
  async function (error, events) {
    /* Handle events here */
  }
})

这样做:

const events = await contract.getPastEvents(
  'allEvents',
  { fromBlock: currentBlock, toBlock: currentBlock }
})
/* Handle events here */