【问题标题】:JavaScript Array filter with async/await带有 async/await 的 JavaScript 数组过滤器
【发布时间】:2021-07-13 22:36:01
【问题描述】:
如下函数:
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;
}
过滤器不起作用并显示所有事务(console.log),并且过滤器循环似乎在之后处理。我想这是一个异步/等待问题。
如何保持过滤器同步?
【问题讨论】:
标签:
javascript
node.js
arrays
async-await
【解决方案1】:
您不能将async 函数用作filter 回调,因为:
-
filter 不会等待承诺得到解决,并且
-
async 函数总是返回承诺,并且所有非null 对象的承诺都是真实的,因此就filter 而言,您返回的标志是您应该保留该元素
在这种情况下,可以使用Promise.all等待所有的交易被检索到,然后过滤结果;见 cmets:
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;
}
所有对web3.eth.getTransaction 的调用将并行启动,然后我们等待所有调用通过await Promise.all(/*...*/) 解决,然后过滤结果并返回。