Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Array filter with async/await

The following function:

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;
}

The filter does not work and all transactions are displayed (console.log), and the filter loops seems to be processed afterwards. I guess it is a async/await problem. How can I keep the the filter synchronous?

like image 841
Homer Avatar asked Jul 24 '26 03:07

Homer


1 Answers

You can't use an async function as a filter callback, because:

  1. filter won't wait for the promises to be settled, and

  2. async functions always return promises, and promises like all non-null objects are truthy, so as far as filter is concerned you're returning a flag saying you should keep the element

In this case, you can use Promise.all to wait for all the transactions to be retrieved and then filter the results; see comments:

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;
}

All of the calls to web3.eth.getTransaction will be started in parallel, then we wait for all of them to settle via await Promise.all(/*...*/), then filter the result and return it.

like image 61
T.J. Crowder Avatar answered Jul 27 '26 03:07

T.J. Crowder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!