关于从块事件监听器中订购承诺的问题

Question about Ordering Promises from Block Event Listeners

我想弄清楚为什么没有按顺序返回块号数据。如果我只是在事件侦听器中打印块号,它会按顺序提供块号,但是当我尝试从该块号中提取块信息并使用“then”方法链接时,它似乎延迟了结果足以对控制台日志进行排序.这可能是我没有完全理解事件循环的结果。任何帮助将不胜感激。

var ethers = require('ethers')
var dotenv = require('dotenv').config({path: '.env'})
var  provider =  new ethers.providers.JsonRpcProvider(process.env.infura_polygon_https)

provider.on('block', (blockNumber) => {
    Promise.resolve()
        .then(() => provider.getBlock(blockNumber))
        .then((message) => console.log(blockNumber + ': ' + message.transactions.length ))
})

console log results

您想延迟记录交易计数,直到所有以前的交易计数都已记录。您可以通过为这些操作建立一个承诺队列来做到这一点:

let queue = Promise.resolve()
provider.on('block', blockNumber => {
    queue = queue.then(() =>
        provider.getBlock(blockNumber)
    ).then(message => {
        console.log(blockNumber + ': ' + message.transactions.length)
    })
})

但是,这是低效的,因为所有 getBlock 调用都必须按顺序发生,并且它不能正确处理错误(可能会破坏整个链)。最好在等待之前的日志完成的同时获取每个块:

let queue = Promise.resolve()
provider.on('block', blockNumber => {
    queue = Promise.all([
        queue,
        provider.getBlock(blockNumber)
    ]).then(([, message] => {
        console.log(blockNumber + ': ' + message.transactions.length)
    }, err => {
        console.error(err.message)
    })
})