函数在继续循环之前不等待条件完成
Posted
技术标签:
【中文标题】函数在继续循环之前不等待条件完成【英文标题】:Function not waiting for conditional to finish before continuing loop 【发布时间】:2021-11-26 15:49:28 【问题描述】:我有这个函数循环遍历每个新区块的交易,然后保存与我的数据库中存储的地址匹配的交易。
块只是一个对象数组。
但是,如果一个事务在不同的块中有事件,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...');
【问题讨论】:
【参考方案1】:你正在混合回调 API 和承诺 API,这永远不会结束。
如果您将函数作为回调传递,则它不应该是async
,也不会是await
ed。
但是getPastEvents
已经返回了一个承诺,所以根本没有理由使用任何回调!
而不是这个...
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 */
【讨论】:
以上是关于函数在继续循环之前不等待条件完成的主要内容,如果未能解决你的问题,请参考以下文章