使用 async/await 的 JavaScript 数组过滤器

Hom*_*mer 7 javascript arrays node.js async-await

以下功能:

async function getPendingTransactions(address){
    var pendingBlock = await web3.eth.getBlock('pending');
    var i = 0;
    var pendingTransactions = await pendingBlock.transactions.filter(async function(txHash)  {
        var tx = await web3.eth.getTransaction(txHash);
        console.log(tx);
        if(tx != null) {
            return tx.from==address && tx.to == CONTRACT_ADDRESS;
        }
    });
    console.log(pendingTransactions);   
    return pendingTransactions;
}
Run Code Online (Sandbox Code Playgroud)

过滤器不起作用并显示所有事务(console.log),并且过滤器循环似乎是在之后处理的。我猜这是一个异步/等待问题。如何保持过滤器同步?

T.J*_*der 10

您不能使用async函数作为filter回调,因为:

  1. filter不会等待承诺得到解决,并且

  2. async函数总是返回承诺,并且像所有非null对象一样的承诺都是真实的,因此就您filter而言,您将返回一个标志,表示您应该保留该元素

这种情况下,可以使用Promise.all等待所有交易检索完毕,然后过滤结果;看评论:

async function getPendingTransactions(address) {
    const pendingBlock = await web3.eth.getBlock("pending");
    // *** Get the transactions by creating an array of promises and then waiting
    // via `await` for all of them to settle
    const transactions = await Promise.all(
        pendingBlock.transactions.map(txHash => web3.eth.getTransaction(txHash))
    );
    // *** Filter them
    const pendingTransactions = transactions.filter(
        tx => tx && tx.from == address && tx.to == CONTRACT_ADDRESS
    );
    return pendingTransactions;
}
Run Code Online (Sandbox Code Playgroud)

所有对 的调用都web3.eth.getTransaction将并行启动,然后我们等待所有调用通过 进行结算await Promise.all(/*...*/),然后过滤结果并返回它。