为何await batch.execute()返回undefined?Web3批量请求问题排查
问题原因及解决方法
核心问题是Web3.js的BatchRequest.execute()不支持直接用await接收返回值,它是基于回调的API,并非Promise兼容方法,直接await会得到undefined。
修正方案
将BatchRequest的执行逻辑包装成Promise,通过回调获取批量请求的结果:
修正后的完整代码
import web3 from "../ethereum/web3"; const range = (start, end, length = end - start + 1) => Array.from({ length }, (_, i) => start + i) export default async function getLatestBlocks(n) { console.log(`Get ${n} Blocks`) const latest = await web3.eth.getBlockNumber(); const blockNumbers = range(latest - n, latest - 1); const batch = new web3.BatchRequest(); const blocks = []; // 为每个请求添加回调,收集结果 blockNumbers.forEach((blockNumber) => { batch.add( web3.eth.getBlock.request( blockNumber, (error, result) => { if (!error) blocks.push(result); // 可根据需求添加错误处理逻辑 } ) ); }); // 将batch执行包装为Promise await new Promise((resolve, reject) => { batch.execute((error) => { if (error) reject(error); else resolve(); }); }); console.log(blocks); return blocks; }
额外注意事项
- 不要把
blocks变量声明在函数外部,否则多次调用函数时会出现数据污染(并发请求互相覆盖)。 - 如果需要保证
blocks顺序和请求的blockNumbers顺序一致,可通过数组下标对应存储(批量请求异步返回,顺序可能不固定),示例:
// 替换原forEach部分 const blocks = new Array(blockNumbers.length); blockNumbers.forEach((blockNumber, index) => { batch.add( web3.eth.getBlock.request( blockNumber, (error, result) => { if (!error) blocks[index] = result; } ) ); });
内容的提问来源于stack exchange,提问作者schmark
相关产品推荐
相关产品推荐

